深度学习之Alexnet学习笔记

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

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

网络模型如图所示:

深度学习之Alexnet学习笔记_第1张图片

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

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,池化后图片大小缩小一半,代码如下:

# 定义卷积操作
def conv2d(name,x, W, b, strides=1):
    # Conv2D wrapper, with bias and relu activation
    x = tf.nn.conv2d(x, W, strides=[1, strides, strides, 1], padding='SAME')
    x = tf.nn.bias_add(x, b)
    return tf.nn.relu(x,name=name)  # 使用relu激活函数

# 定义池化层操作
def maxpool2d(name,x, k=2):
    # MaxPool2D wrapper
    return tf.nn.max_pool(x, ksize=[1, k, k, 1], strides=[1, k, k, 1],
                          padding='SAME',name=name)

# 规范化操作
def norm(name, l_input, lsize=4):
    return tf.nn.lrn(l_input, lsize, bias=1.0, alpha=0.001 / 9.0,
                     beta=0.75, name=name)

def alex_net(x, weights, biases, dropout):
    # 向量转为矩阵 Reshape input picture
    x = tf.reshape(x, shape=[-1, 28, 28, 1])

    # 第一层卷积
    # 卷积
    conv1 = conv2d('conv1', x, weights['wc1'], biases['bc1'])
    # 下采样
    pool1 = maxpool2d('pool1', conv1, k=2)
    # 规范化
    norm1 = norm('norm1', pool1, lsize=4)

Alexnet网络第二层:

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

Alexnet网络第三层:

# 卷积
    conv3 = conv2d('conv3', norm2, weights['wc3'], biases['bc3'])
    # 规范化
    norm3 = norm('norm3', conv3, lsize=4)
Alexnet网络第四层:
  # 第四层卷积
    conv4 = conv2d('conv4', norm3, weights['wc4'], biases['bc4'])
 # 第五层卷积
    conv5 = conv2d('conv5', conv4, weights['wc5'], biases['bc5'])
    # 最大池化(向下采样)
    pool5 = maxpool2d('pool5', conv5, k=2)
    # 规范化
    norm5 = norm('norm5', pool5, lsize=4)
# 全连接层1
    fc1 = tf.reshape(norm5, [-1, weights['wd1'].get_shape().as_list()[0]])
    fc1 =tf.add(tf.matmul(fc1, weights['wd1']),biases['bd1'])
    fc1 = tf.nn.relu(fc1)
    # dropout
    fc1=tf.nn.dropout(fc1,dropout)

    # 全连接层2
    fc2 = tf.reshape(fc1, [-1, weights['wd2'].get_shape().as_list()[0]])
    fc2 =tf.add(tf.matmul(fc2, weights['wd2']),biases['bd2'])
    fc2 = tf.nn.relu(fc2)
    # dropout
    fc2=tf.nn.dropout(fc2,dropout)

    # 输出层
    out = tf.add(tf.matmul(fc2, weights['out']) ,biases['out'])
    return out
# 构建模型
pred = alex_net(x, weights, biases, keep_prob)

# 定义损失函数和优化器
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y,logits=pred))
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)

# 评估函数
correct_pred = tf.equal(tf.argmax(pred,1), tf.argmax(y,1))
accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))

# 初始化变量
init = tf.global_variables_initializer()
saver=tf.train.Saver()
# 开启一个训练
with tf.Session() as sess:
    sess.run(init)
    step = 1
    # 开始训练,直到达到training_iters,即200000
    while step * batch_size < training_iters:
        #获取批量数据
        batch_x, batch_y = mnist.train.next_batch(batch_size)
        sess.run(optimizer, feed_dict={x: batch_x, y: batch_y, keep_prob: dropout})
        if step % display_step == 0:
            # 计算损失值和准确度,输出
            loss,acc = sess.run([cost,accuracy], feed_dict={x: batch_x, y: batch_y, keep_prob: 1.})
            print ("Iter " + str(step*batch_size) + ", Minibatch Loss= " + "{:.6f}".format(loss) + ", Training Accuracy= " + "{:.5f}".format(acc))
        step += 1
    #储存模型
    save_path=saver.save(sess,'model/save_alexnet.ckpt')
    #输出储存路径
    print('SAVE TO PATH',save_path)
    
    print ("Optimization Finished!")
    # 计算测试集的精确度
    print ("Testing Accuracy:",
           sess.run(accuracy, feed_dict={x: mnist.test.images[:256],
                                         y: mnist.test.labels[:256],
                                         keep_prob: 1.}))

预测函数编写:

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


你可能感兴趣的:(深度学习之Alexnet学习笔记)