立即学习:https://edu.csdn.net/course/play/24719/279509?utm_source=blogtoedu
目录
一、神经网络训练代码
二、思路总结
1、数据集图片数据、目标值的导入
2、目标值转化为one_hot编码
3、神经网络中样本、目标的输入
4、神经网络的搭建
5、损失的计算与优化
6、批处理的方法
7、准确率的计算
8、模型的保存
三、API总结
图片数据
首先,用cv读取图片,将图片一个一个添加到一个list里面去。
其次,用np(numpy)将图片的列表转化为np数组。
图片目标值
首先,由于图片被按照目录分类
在读取图片时,每读取一张图,就将图片的上级目录的名字作为一个目标值。(这里是0、1、2)
步骤如下:
原本一个样本只有一个目标值
一共600个样本,目标值总的可能性有3种(某种目标的one_hot编码就只可能是[1, 0, 0]、[0, 1, 0]、[0, 0, 1])
先生成好一个全零的、形状为(600, 3)的np数组𝐴,准备将值1填入对应标签位置的位置
准备好每个样本在𝐴展平后的数组𝐵中的one_hot特征下标
将1填入上一步中展平下标对应在数组𝐴中的位置
可以通过一个占位符来实现,个数的那一维填写None,代表暂时不知道每次训练的样本数量,在实际训练中会根据每批次训练数量加以给定。
比如,我们这里的样本数为600,每个样本的形状都是(100, 100, 3),也就是总的样本的形状为(600, 100, 100, 3),那么我们样本输入的占位符的形状就应该为(None, 100, 100, 3);同样地,我们one_hot目标值的形状为(600, 3),那么我们样本目标值的占位符形状就应该为(None, 3)
步骤如下:
接入一个卷积层(tf.layers.conv2d)
第一个参数(inputs)为输入数据
第二个参数(filters)为卷积核的数量
第三个参数(kernel_size)为卷积核的大小
(这里因为我们的数据比较简单、类别也少,所以filters取了比较小的值4)
(如果像是imagenet那种大型数据集一般会取到128或者256那样)
接入一个池化层(用于减少数据量)(tf.layers.max_pooling2d)
第一个参数(inputs)为输入
第二个参数(pool_size)为池化核的大小
第三个参数(strides)为卷积核的步长
(这里我们都把pool_size和strides设置为2)
加上一个激活函数ReLU
把神经网络的输出拍扁,做成一个一维数组
添加几个全连接层(tf.layers.dense)
第一个参数(inputs)为输入
第二个参数(unit)为输出的维度大小(改变inputs的最后一维),同时也是神经元的个数
(一开始中间加入的是一层,后来发现一层全连接层训练的效果不怎么好,改成了两层)
再接入一个全连接层得到输出
(注意,输出的分类数要和目标label的分类数相同,否则会报错)
损失计算
计算交叉熵损失
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(labels=label_in, logits=pred))优化
使用Adam优化算法
train_op = tf.train.AdamOptimizer(learning_rate=0.001).minimize(loss)步骤如下:
设置每批次的训练数量batch_size、训练的趟数
每趟训练前件训练用的输入数据随机打乱
计算好每一趟训练的批次数量,对每一批次用batch_size个样本进行训练
步骤如下:
找到预测值、目标值的每一个样本在one_hot编码中的横向下标
tf.argmax(pred, 1, name="output") tf.argmax(label_in, 1)对比预测值、目标值的下标值是否相等,由此得到一个判断对应样本的预测值与目标值是否相等的tf张量
correct_prediction = tf.equal(tf.argmax(pred, 1), tf.argmax(label_in, 1))从上面的比对张量中计算平均值,得到这一批次的准确率
在一趟训练结束后,将所有批次准确率相加求和,再除以训练批次数量,就得到了这一趟训练的平均准确率
步骤如下:
构造一个tf模型存储器
saver = tf.train.Saver()指定会话、模型存储路径
saver.save(sess, './目录/模型名')这里需要注意的是,我们需要为输入数据占位符data_in、预测值out_label增加上各自的name,这是为了之后模型读取的方便
API
作用
使用示例
glob.glob
返回某个路径下所有被匹配的文件/目录路径生成的列表
for cls_path in glob.glob(os.path.join(dataset_path, '*')):
......
np.array
根据某种数据类型的值生成相应的np数组
data_np = np.array(data_list)
np.arange
按照指定的start、stop、step生成一个指定的np一维等差数组
index_offset = np.arange(num_label) * num_class
np.zeros
按照指定的shape生成元素全为0的np数组
label_one_hot = np.zeros((num_label, num_class))
*.flat[???]
根据数组展平后的下标获取数组元素
label_one_hot.flat[index_offset + label.ravel()] = 1
np.random.shuffle
随机打乱一串数
np.random.shuffle(idx)
tf.placeholder
创建一个tf占位符
label_in = tf.placeholder(tf.float32, [None, 3])
tf.Session
创建一个tf会话
with tf.Session() as sess:
......
tf.initialize_all_variables
创建一个tf变量初始化op
init_op = tf.initialize_all_variables()
tf.train.Saver
创建一个tf会话存储器
saver = tf.train.Saver()
*.save
保存会话中的训练模型
saver.save(sess, './model/model')
tf.argmax
找出张量在某一维度上的最大值对应的下标
out_label = tf.argmax(pred, 1, name="output")
tf.reduce_mean
计算平均值
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
tf.cast
将某个张量的数据类型进行转换
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
tf.equal
按元素比较两个张量,返回相等情况对应的张量
correct_prediction = tf.equal(out_label, tf.argmax(label_in, 1))
tf.nn.
softmax_cross_entropy
_with_logits_v2
计算交叉熵损失
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(labels=label_in, logits=pred))
tf.layers.conv2d
构建卷积层
out = tf.layers.conv2d(data_in, 4, 3, padding='same')
tf.layers.max_pooling2d
构建池化层
out = tf.layers.max_pooling2d(out, 2, 2, padding='same')
tf.nn.relu
激活函数ReLU
out = tf.nn.relu(out)
tf.layers.dense
构造全连接层
out = tf.layers.dense(out, 2000, activation=tf.nn.relu)