深度学习之Alexnet学习笔记

声明:本文主要是谈谈对CNN中的Alexnet网络学习的感想,本人初学者,如有错误的地方欢迎指正。文章部分内容来源于网络诸位大神,所以如有相同的地方,望谅解。本文只适用于交流学习。文章后面是我利用Alexnet网络对MNIST数字识别进行训练的模型,并写了一个输入图片进行预测的程序。

Alexnet网络 训练了一个大规模的深度卷积神经网络来将ImageNet LSVRC-2010比赛中的包含120万幅高分辨率的图像数据集分为1000种不同类别。该 神经网络包含6千万个参数和65万个神经元,包含了5个卷积层,其中有几层后面跟着最大池化(max-pooling)层,以及3个全连接层,最后还有一个1000路的softmax层。为了加快训练速度,该网络使用了不饱和神经元以及一种高效的基于GPU的卷积运算方法。为了减少全连接层的过拟合,该网络采用了最新的正则化方法“dropout”。

网络模型如图所示:

基于原文的解读,该网络主要优点有一下四点:

1、 数据增强,提出"dropout"方法 (减少过拟合)

2、重叠pool池化(提高精度、不容易产生过拟合)

3、局部响应归一化(提高精度)

4、ReLU、两个GPU同时训练(提高速度)

下面我用训练MNIST数字识别的类型来谈谈对Alexnet网络的理解:

MNIST是一个简单的视觉计算数据集,它是像下面这样手写的数字图片:

每张图片还额外有一个标签记录了图片上数字是几,例如上面几张图的标签就是:5、0、4、1。 

本次将会展现如何训练一个模型来识别这些图片,最终实现模型对图片上的数字进行预测。

首先是对网络的结构分析,mnist数据是28*28的图片,扩展之后是(1,784)的数据,Alexnet网络第一层卷积神经网络是卷积层+池化层+norm,卷积网络是利用96个11*11*1的滤波器,卷积是都采用padding补齐,卷积后图片大小不变,池化层是2*2*1,步长为2,池化后图片大小缩小一半,代码如下:

1# 定义卷积操作 2def conv2d(name,x, W, b, strides=1): 3 # Conv2D wrapper, with bias and relu activation 4 x = tf.nn.conv2d(x, W, strides=[1, strides, strides, 1], padding='SAME') 5 x = tf.nn.bias_add(x, b) 6 return tf.nn.relu(x,name=name) # 使用relu激活函数 7 8# 定义池化层操作 9def maxpool2d(name,x, k=2): 10 # MaxPool2D wrapper 11 return tf.nn.max_pool(x, ksize=[1, k, k, 1], strides=[1, k, k, 1], 12 padding='SAME',name=name) 13 14# 规范化操作 15def norm(name, l_input, lsize=4): 16 return tf.nn.lrn(l_input, lsize, bias=1.0, alpha=0.001 / 9.0, 17 beta=0.75, name=name) 18
1def alex_net(x, weights, biases, dropout): 2 # 向量转为矩阵 Reshape input picture 3 x = tf.reshape(x, shape=[-1, 28, 28, 1]) 4 5 # 第一层卷积 6 # 卷积 7 conv1 = conv2d('conv1', x, weights['wc1'], biases['bc1']) 8 # 下采样 9 pool1 = maxpool2d('pool1', conv1, k=2) 10 # 规范化 11 norm1 = norm('norm1', pool1, lsize=4) 12

Alexnet网络第二层:

1# 第二层卷积 2 # 卷积 3 conv2 = conv2d('conv2', norm1, weights['wc2'], biases['bc2']) 4 # 最大池化(向下采样) 5 pool2 = maxpool2d('pool2', conv2, k=2) 6 # 规范化 7 norm2 = norm('norm2', pool2, lsize=4) 8

Alexnet网络第三层:

1# 卷积 2 conv3 = conv2d('conv3', norm2, weights['wc3'], biases['bc3']) 3 # 规范化 4 norm3 = norm('norm3', conv3, lsize=4) 5

Alexnet网络第四层:

1 # 第四层卷积 2 conv4 = conv2d('conv4', norm3, weights['wc4'], biases['bc4']) 3
1 # 第五层卷积 2 conv5 = conv2d('conv5', conv4, weights['wc5'], biases['bc5']) 3 # 最大池化(向下采样) 4 pool5 = maxpool2d('pool5', conv5, k=2) 5 # 规范化 6 norm5 = norm('norm5', pool5, lsize=4) 7
1# 全连接层1 2 fc1 = tf.reshape(norm5, [-1, weights['wd1'].get_shape().as_list()[0]]) 3 fc1 =tf.add(tf.matmul(fc1, weights['wd1']),biases['bd1']) 4 fc1 = tf.nn.relu(fc1) 5 # dropout 6 fc1=tf.nn.dropout(fc1,dropout) 7 8 # 全连接层2 9 fc2 = tf.reshape(fc1, [-1, weights['wd2'].get_shape().as_list()[0]]) 10 fc2 =tf.add(tf.matmul(fc2, weights['wd2']),biases['bd2']) 11 fc2 = tf.nn.relu(fc2) 12 # dropout 13 fc2=tf.nn.dropout(fc2,dropout) 14 15 # 输出层 16 out = tf.add(tf.matmul(fc2, weights['out']) ,biases['out']) 17 return out 18
1# 构建模型 2pred = alex_net(x, weights, biases, keep_prob) 3 4# 定义损失函数和优化器 5cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y,logits=pred)) 6optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost) 7 8# 评估函数 9correct_pred = tf.equal(tf.argmax(pred,1), tf.argmax(y,1)) 10accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32)) 11 12# 初始化变量 13init = tf.global_variables_initializer() 14saver=tf.train.Saver() 15# 开启一个训练 16with tf.Session() as sess: 17 sess.run(init) 18 step = 1 19 # 开始训练,直到达到training_iters,即200000 20 while step * batch_size < training_iters: 21 #获取批量数据 22 batch_x, batch_y = mnist.train.next_batch(batch_size) 23 sess.run(optimizer, feed_dict={x: batch_x, y: batch_y, keep_prob: dropout}) 24 if step % display_step == 0: 25 # 计算损失值和准确度,输出 26 loss,acc = sess.run([cost,accuracy], feed_dict={x: batch_x, y: batch_y, keep_prob: 1.}) 27 print ("Iter " + str(step*batch_size) + ", Minibatch Loss= " + "{:.6f}".format(loss) + ", Training Accuracy= " + "{:.5f}".format(acc)) 28 step += 1 29 #储存模型 30 save_path=saver.save(sess,'model/save_alexnet.ckpt') 31 #输出储存路径 32 print('SAVE TO PATH',save_path) 33 34 print ("Optimization Finished!") 35 # 计算测试集的精确度 36 print ("Testing Accuracy:", 37 sess.run(accuracy, feed_dict={x: mnist.test.images[:256], 38 y: mnist.test.labels[:256], 39 keep_prob: 1.})) 40

预测函数编写:

1#图片加载展示 2my_image = "1.jpg" 3# END CODE HERE # 4fname = "images/" + my_image 5image = np.array(ndimage.imread(fname, flatten=False)) 6img = Image.fromarray(image.reshape([28,28])) 7img.show() 8my_image = scipy.misc.imresize(image, size=( 28, 28)).reshape((1, 28*28*1))/255 9# plt.imshow(image) 10# pylab.show() 11#图片预测 12x = tf.placeholder("float", [1, 784]) 13p = alex_net(x,weights,biases,dropout) 14pr = tf.nn.softmax(p) 15saver = tf.train.Saver() 16with tf.Session() as sess: 17 save_path = saver.restore(sess, 'model/save_alexnet.ckpt') 18 prediction = sess.run(pr, feed_dict={x: my_image}) 19 i=sess.run(tf.argmax(prediction, 1)) 20print("Your algorithm predicts: y = %d"%i) 21
1具体代码见我的资源上传 2

代码交流 2021