TensorFlow 1.x 实战--训练BP神经网络
本文于
1238
天之前发表,文中内容可能已经过时。
BP(back propagation)神经网络是1986年由Rumelhart和McClelland为首的科学家提出的概念,是一种按照误差逆向传播算法训练的多层前馈神经网络,是目前应用中最基本的神经网络。
BP(back propagation)神经网络是1986年由Rumelhart和McClelland为首的科学家提出的概念,是一种按照误差逆向传播算法训练的多层前馈神经网络,是目前应用中最基本的神经网络。
运行环境:tensorflow1.14.0
新建程序文件 打开ide 我这里使用的是jupyter notebook,优点是容易调试,简单清爽。
在终端输入jupyter notebook即可在浏览器里面打开,windows是在cmd里面输入。
载入必要的库 1 2 3 4 5 6 7 8 9 import tensorflow as tfimport numpy as npimport matplotlib.pyplot as plt%matplotlib inline from skimage.io import imreadfrom skimage.transform import resizeimport osimport random
载入封装好的函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 def weight_variable (shape ): initial = tf.truncated_normal(shape, mean=0 , stddev=0.01 ) return tf.Variable(initial) def bias_variable (shape ): initial = tf.constant(0.1 , shape=shape) return tf.Variable(initial) def fulc (x,next_depth ): depth = x.get_shape()[-1 ].value w = weight_variable([depth, next_depth]) b = bias_variable([next_depth]) r = tf.nn.relu(tf.nn.bias_add(tf.matmul(x, w), b)) return r
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 def load_images (path ): contents = os.listdir(path) classes = [each for each in contents if os.path.isdir(os.path.join(path,each))] print ('目录下有%s' % classes) labels = [] images = [] for each in classes: class_path = os.path.join(path,each) files = os.listdir(class_path) print ("Starting {} images" .format (each),'数量为' ,len (files)) for ii, file in enumerate (files, 1 ): img = imread(os.path.join(class_path, file)) img = img / 255.0 img = resize(img, (32 , 32 )) images.append(img.reshape((32 ,32 ,3 ))) labels.append(each) images = np.array(images) from sklearn.preprocessing import LabelBinarizer lb = LabelBinarizer() lb.fit(labels) labels_vecs = lb.transform(labels) print ('总共读取了%d张图片' %images.shape[0 ]) return images,labels_vecs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 def next_batch (train_data, train_target, batch_size ): index = [ i for i in range (0 ,len (train_data))] np.random.shuffle(index); batch_data = np.zeros((batch_size,train_data.shape[1 ],train_data.shape[2 ],train_data.shape[3 ])); batch_target = np.zeros((batch_size,train_target.shape[1 ])); rand = random.randint(1 ,4 )*2 for i in range (0 ,batch_size): batch_data[i,:,:,:] = train_data[index[i],:,:,:] batch_target[i,:] = train_target[index[i],:] state = np.random.get_state() np.random.shuffle(batch_data) np.random.set_state(state) np.random.shuffle(batch_target) return batch_data, batch_target
封装神经网络结构 把上面的封装好的函数拿来用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 def create (x_images,keep_prob ): h,w,d=x_images.get_shape().value h_conv_flat = tf.reshape(x_images,[-1 ,h*w*d]) h_fc1 = fulc(h_conv_flat,1024 ) h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob) h_fc2 = fulc(h_fc1_drop,1024 ) h_fc2_drop = tf.nn.dropout(h_fc2, keep_prob) h_fc3 = fulc(h_fc2_drop,1 ) out = tf.nn.sigmoid(h_fc3,name='out' ) print ('模型建立好了!' ) return out
tensorflow特色占位 在tensorflow1.x版本内,训练前需要先在内存中“占位”。
既然如此,我们把模型创建、损失函数的定义、准确率的定义也放到这一块。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 x_images = tf.placeholder(tf.float32,[None ,32 ,32 ,3 ],name='x_images' ) y = tf.placeholder(tf.float32,[None ,1 ],name='y' ) keep_prob = tf.placeholder(tf.float32,name='keep_prob' ) y_conv = create(x_images,keep_prob) pred = tf.round (y_conv,name='predict' ) cross_entropy = tf.reduce_mean(tf.reduce_mean(tf.square(y_conv-y)),name='cross_entropy' ) train_step = tf.compat.v1.train.AdamOptimizer(1e-4 ).minimize(cross_entropy) correct_prediction = tf.equal(pred,y) correct_prediction = tf.cast(correct_prediction, tf.float32) accuracy = tf.reduce_mean(correct_prediction,name='accuracy' )
开始训练 训练目标:训练集{batch_x,batch_y}100%正确
训练集:从{train_x,train_y}中抽取20对
每10次迭代打印并记录一次loss&acc值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 saver = tf.compat.v1.train.Saver() with tf.Session() as sess: sess.run(tf.compat.v1.global_variables_initializer()) step = 1 acc=0 while acc!=1 : batch_x,batch_y = next_batch(train_x,train_y,20 ) _ = sess.run(train_step,feed_dict={x_images: batch_x, y: batch_y, keep_prob: 0.75 }) if step % 10 == 0 : predt,acc,loss=sess.run([pred,accuracy,cross_entropy],feed_dict={x_images: batch_x, y: batch_y, keep_prob: 1. }) print ('step:%d,train loss:%f' % (step,loss)) print ('train accuracy:%f' % acc) with open ("trainloss.txt" ,"a+" ) as f: f.write('step:%d,train loss:%f\n' % (step,loss)) if step==10 : l = np.array(loss) a = np.array(acc) s = np.array(step) else : l = np.append(l,np.array(loss)) a = np.append(a,np.array(acc)) s = np.append(s,np.array(step)) step += 1 saver.save(sess,"./model/net.ckpt" )
训练过程的可视化 使用以下代码
1 2 3 4 5 6 7 8 9 10 plt.plot(s,l)plt.title('step-loss' ) plt.xlabel('step' ) plt.ylabel('loss' ) plt.show() plt.plot(s,a) plt.title('step-acc' ) plt.xlabel('step' ) plt.ylabel('acc' ) plt.show()
效果如图:
最后: 本次实验中训练次数较少,且没有设置测试集或验证集,因此仅能作为参考,具体项目切不可如此。