【基于tensorflow的学习】经典卷积神经网络、模型的保存和读取

 CNN发展史:

1.经典卷积神经网络

以下仅列出关于CNN的深层次理解:

卷积层

tensorflow中卷积层的建立函数:_conv1 = tf.nn.conv2d(_input_r, tf.Variable(tf.random_normal([3, 3, 1, 64], stddev=0.1)), strides=[1, 1, 1, 1], padding='SAME')  参数说明:

  1. 输入图像
  2. tensor变量建立(正态分布初始化(filter_height,fileter_width,in_channels,out_channels],方差))
  3. stride=[1,stride,stride,1]
  4. padding='SAME'or'VALID'(same是圈圈取零包裹)

 

  1. 卷积核的通道数必须与输入的一致,但可以有多个卷积核,如此输出通道数便增多了
  2. 经过卷积核之后的输出图像大小:以高为例:   \mathbf{h_{o}=\frac{h_{i}-h_{kernal}+2*padding}{stride}+1}
  3. 卷积核的意义,其实就跟图像处理当中的“图像分割”里线检测、边缘检测用的算子一般:线检测算子--水平、+45°、-45°、垂直;边缘检测算子:sobel、prewitt、Laplacian等,这些是基于图像的突变性和连续性,从“一阶导数”、“二阶导数”等数学原理所推导出来的几何特征的提取算子。而我们利用神经网络的BP反馈对卷积核进行训练,则这个算子则能够帮助我们提取我们所需要的特征。
  4. 卷积核的分类--扩张卷积、转置卷积、可分离卷积:http://www.sohu.com/a/159591827_390227
  5. padding边缘填充是为了不让一些边界消失,分为full、same、valid。
  6. “局部连接”--每个神经元(卷积层的一个像素)仅与输入神经元的一块区域(输入图像的一个局部区域)连接,这块局部区域称作感受野。如此保证了学习后的过滤器能够对于局部的输入特征有最强的响应。局部连接的思想,也是受启发于生物学里面的视觉系统结构,视觉皮层的神经元就是局部接受信息的;而且局部连接使得参数大量减少。
  7. “权值共享”--计算同一个深度切片的神经元时采用的滤波器是共享的。共享权重在一定程度上讲是有意义的,例如图片的底层边缘特征与特征在图中的具体位置无关。但是在一些场景中是无意的,比如输入的图片是人脸,眼睛和头发位于不同的位置,希望在不同的位置学到不同的特征 (参考斯坦福大学公开课)。请注意权重只是对于同一深度切片的神经元是共享的,在卷积层,通常采用多组卷积核提取不同特征,即对应不同深度切片的特征,不同深度切片的神经元权重是不共享,如此组成的特征即为Feature map。另外,偏重对同一深度切片的所有神经元都是共享的。
  8. “分布式表征”--神经网络的重要性质,即如“编码”一般,可将样本从原始空间投影到一个更好的特征空间中。

池化层

tensorflow中池化层的建立函数:_pool1 = tf.nn.max_pool(_conv1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')

  1. 池化层的作用:通过池化来降低卷积层输出的特征向量,同时改善结果(不易出现过拟合)。
  2. 池化层的操作:max、mean。
  3. “区域不变形”--pooling 这步综合了局部特征,失去了每个特征的位置信息。这很适合基于图像的任务,比如要判断一幅图里有没有猫这种生物,你可能不会去关心这只猫出现在图像的哪个区域。但是在 NLP 里,词语在句子或是段落里出现的位置,顺序,都是很重要的信息。

一个经典卷积神经网络的实现:input-conv1-relu-pooling1-conv2-relu-pooling2-dc1-output

n_input  = 784
n_output = 10
weights  = {
        'wc1': tf.Variable(tf.random_normal([3, 3, 1, 64], stddev=0.1)),
        'wc2': tf.Variable(tf.random_normal([3, 3, 64, 128], stddev=0.1)),
        'wd1': tf.Variable(tf.random_normal([7*7*128, 1024], stddev=0.1)),
        'wd2': tf.Variable(tf.random_normal([1024, n_output], stddev=0.1))
    }
biases   = {
        'bc1': tf.Variable(tf.random_normal([64], stddev=0.1)),
        'bc2': tf.Variable(tf.random_normal([128], stddev=0.1)),
        'bd1': tf.Variable(tf.random_normal([1024], stddev=0.1)),
        'bd2': tf.Variable(tf.random_normal([n_output], stddev=0.1))
    }
def conv_basic(_input, _w, _b, _keepratio):
        # INPUT
        _input_r = tf.reshape(_input, shape=[-1, 28, 28, 1])
        # CONV LAYER 1
        _conv1 = tf.nn.conv2d(_input_r, _w['wc1'], strides=[1, 1, 1, 1], padding='SAME')
        #_mean, _var = tf.nn.moments(_conv1, [0, 1, 2])
        #_conv1 = tf.nn.batch_normalization(_conv1, _mean, _var, 0, 1, 0.0001)
        _conv1 = tf.nn.relu(tf.nn.bias_add(_conv1, _b['bc1']))
        _pool1 = tf.nn.max_pool(_conv1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
        _pool_dr1 = tf.nn.dropout(_pool1, _keepratio)
        # CONV LAYER 2
        _conv2 = tf.nn.conv2d(_pool_dr1, _w['wc2'], strides=[1, 1, 1, 1], padding='SAME')
        #_mean, _var = tf.nn.moments(_conv2, [0, 1, 2])
        #_conv2 = tf.nn.batch_normalization(_conv2, _mean, _var, 0, 1, 0.0001)
        _conv2 = tf.nn.relu(tf.nn.bias_add(_conv2, _b['bc2']))
        _pool2 = tf.nn.max_pool(_conv2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
        _pool_dr2 = tf.nn.dropout(_pool2, _keepratio)
        # VECTORIZE
        _dense1 = tf.reshape(_pool_dr2, [-1, _w['wd1'].get_shape().as_list()[0]])
        # FULLY CONNECTED LAYER 1
        _fc1 = tf.nn.relu(tf.add(tf.matmul(_dense1, _w['wd1']), _b['bd1']))
        _fc_dr1 = tf.nn.dropout(_fc1, _keepratio)
        # FULLY CONNECTED LAYER 2
        _out = tf.add(tf.matmul(_fc_dr1, _w['wd2']), _b['bd2'])
        # RETURN
        out = { 'input_r': _input_r, 'conv1': _conv1, 'pool1': _pool1, 'pool1_dr1': _pool_dr1,
            'conv2': _conv2, 'pool2': _pool2, 'pool_dr2': _pool_dr2, 'dense1': _dense1,
            'fc1': _fc1, 'fc_dr1': _fc_dr1, 'out': _out
        }
        return out
print ("CNN READY")
x = tf.placeholder(tf.float32, [None, n_input])
y = tf.placeholder(tf.float32, [None, n_output])
keepratio = tf.placeholder(tf.float32)

# FUNCTIONS

_pred = conv_basic(x, weights, biases, keepratio)['out']
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y, logits=_pred))
#使用了最先进的adam优化算法,其中包含了正则化的思想,但不像传统的正则化那样。
optm = tf.train.AdamOptimizer(learning_rate=0.001).minimize(cost)
_corr = tf.equal(tf.argmax(_pred,1), tf.argmax(y,1)) 
accr = tf.reduce_mean(tf.cast(_corr, tf.float32)) 
init = tf.global_variables_initializer()
    
# SAVER
print ("GRAPH READY")
sess = tf.Session()
sess.run(init)

training_epochs = 30
batch_size      = 10
display_step    = 5
time1=time.time()
for epoch in range(training_epochs):
    avg_cost = 0.
    total_batch = int(mnist.train.num_examples/batch_size)
    #total_batch = 10
    # Loop over all batches
    for i in range(total_batch):
        batch_xs, batch_ys = mnist.train.next_batch(batch_size)
        # Fit training using batch data
        sess.run(optm, feed_dict={x: batch_xs, y: batch_ys, keepratio:0.7})
        # Compute average loss
        avg_cost += sess.run(cost, feed_dict={x: batch_xs, y: batch_ys, keepratio:1.})/total_batch

    # Display logs per epoch step
    if epoch % display_step == 0: 
        print ("Epoch: %03d/%03d cost: %.9f" % (epoch, training_epochs, avg_cost))
        train_acc = sess.run(accr, feed_dict={x: batch_xs, y: batch_ys, keepratio:1.})
        print (" Training accuracy: %.3f" % (train_acc))
        test_acc = sess.run(accr, feed_dict={x: testimg, y: testlabel, keepratio:1.})
        print (" Test accuracy: %.3f" % (test_acc))

print ("OPTIMIZATION FINISHED")
time_waste=time.time()-time1
print("The time wasting is:%dh %dm %ds"%(time_waste//(60*24),time_waste%(60*24)//60,time_waste%(60*24)%60))
Epoch: 000/030 cost: 0.122792258
 Training accuracy: 0.900
 Test accuracy: 0.986
Epoch: 005/030 cost: 0.012638518
 Training accuracy: 1.000
 Test accuracy: 0.993
Epoch: 010/030 cost: 0.006675720
 Training accuracy: 1.000
 Test accuracy: 0.992
Epoch: 015/030 cost: 0.005300980
 Training accuracy: 1.000
 Test accuracy: 0.992
Epoch: 020/030 cost: 0.003683299
 Training accuracy: 1.000
 Test accuracy: 0.990
Epoch: 025/030 cost: 0.003249645
 Training accuracy: 1.000
 Test accuracy: 0.993
OPTIMIZATION FINISHED
The time wasting is:0h 13m 54s

2.Alexnet

以上程序很多地方其实已经用到了Alexnet的特点了:像是RELU、dropout。

Alexnet的特点实际上就是:

  1. 采用了三个链接层:2048、2048、1000
  2. 激活函数采用relu
  3. 全链接层采用dropout
  4. 在relu和pool之间采用局部相应归一化LRN,但是当net的层数到达11层时,这个lrn没有作用,反而起了副作用;而且因为lrn在池化层前的计算会不经济,所以后面的alexnet改进有把lrn放在了pool后面
  5. conv-pool数更多了,达到5个
  6. GPUS分布式计算,如图所示
  7. 扩展数据:随机裁剪、旋转......

LRN的介绍:

 

 参数可以百度LRN看看,这里讲讲它的含义--来源于《深度学习与计算机视觉》

局部相应归一化模拟的是动物神经中的横向抑制效应(将相似的记忆分开),从公式可以看出,如果在该位置,该通道和临近通道的绝对值都比较大的话,归一化之后值会有变得更小的趋势。

3.模型的保存和读取

#保存模型
saver = tf.train.Saver(max_to_keep=3)#最多保存三个模型,再存入则会按照first delete
saver.save(sess, "save/nets/cnn_mnist_basic.ckpt-" + str(epoch))#将训练好的计算图存入该文件

#读取模型
epoch = training_epochs-1
saver.restore(sess, "save/nets/cnn_mnist_basic.ckpt-" + str(epoch))

test_acc = sess.run(accr, feed_dict={x: testimg, y: testlabel, keepratio:1.})
print (" TEST ACCURACY: %.3f" % (test_acc))

参考资料:https://github.com/scutan90/DeepLearning-500-questions

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
神经网络(Convolutional Neural Network,CNN)是一种深度学习模型,广泛应用于图像识别、语音识别、自然语言处理等领域。Python是一种功能强大的编程语言,具有广泛的应用和支持,而且有许多流行的深度学习框架可供使用,如TensorFlow、PyTorch、Keras等,因此Python成为卷神经网络实现的首选语言。 通过Python实现卷神经网络,可以便捷地构建高级深度学习模型。在Python的各种深度学习框架中,提供了许多卷神经网络的类和函数,这些类和函数可以轻松地创建卷层、池化层和全连接层等各种网络层,并调整参数、优化模型,最终得到一个准确率高、效果好的深度学习模型。 卷神经网络在Python中的实现主要分为以下几个步骤: 1.准备数据集:选择对应的数据集,使用Python的数据处理库对数据进行读取、清洗和预处理。 2.构建卷神经网络模型:使用Python的深度学习框架,通过堆叠卷层、池化层和全连接层等组成卷神经网络模型。 3.训练模型:使用Python的深度学习框架对模型进行训练,通过对数据集进行多次迭代训练,对卷神经网络模型进行优化,提高模型准确率。 4.测试模型:使用Python的深度学习框架对卷神经网络模型进行测试,测试不同数据集下模型的准确率和性能。 通过Python实现卷神经网络,可以有效提高深度学习模型的准确度和可靠性,为图像识别、语音识别等领域提供了强有力的支持。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值