用tensorflow实现VGG网络,训练mnist数据集

VGG作为流行的几个模型之一,训练图形数据效果不错,在mnist数据集是常用的入门集数据,VGG层数非常多,如果严格按照规范来实现,并用来训练mnist数据集,会出现各种问题,如,经过16层卷积后,28*28*1的图片几乎无法进行。

先介绍下VGG

 
 
   
   
ILSVRC 2014的第二名是Karen Simonyan和 Andrew Zisserman实现的卷积神经网络,现在称其为 VGGNet。它主要的贡献是展示出网络的深度是算法优良性能的关键部分。
他们最好的网络包含了16个卷积/全连接层。网络的结构非常一致,从头到尾全部使用的是3x3的卷积和2x2的汇聚。他们的 预训练模型是可以在网络上获得并在Caffe中使用的。
VGGNet不好的一点是它耗费更多计算资源,并且使用了更多的参数,导致更多的内存占用(140M)。其中绝大多数的参数都是来自于第一个全连接层。

模型结构:



本文在实现时候,尽量保存VGG原来模型结构,核心代码如下:


weights ={
    'wc1':tf.Variable(tf.random_normal([3,3,1,64])),
    'wc2':tf.Variable(tf.random_normal([3,3,64,64])),
    'wc3':tf.Variable(tf.random_normal([3,3,64,128])),
    'wc4':tf.Variable(tf.random_normal([3,3,128,128])),
    
    'wc5':tf.Variable(tf.random_normal([3,3,128,256])),
    'wc6':tf.Variable(tf.random_normal([3,3,256,256])),
    'wc7':tf.Variable(tf.random_normal([3,3,256,256])),
    'wc8':tf.Variable(tf.random_normal([3,3,256,256])),
    
    'wc9':tf.Variable(tf.random_normal([3,3,256,512])),
    'wc10':tf.Variable(tf.random_normal([3,3,512,512])),
    'wc11':tf.Variable(tf.random_normal([3,3,512,512])),
    'wc12':tf.Variable(tf.random_normal([3,3,512,512])),
    'wc13':tf.Variable(tf.random_normal([3,3,512,512])),
    'wc14':tf.Variable(tf.random_normal([3,3,512,512])),
    'wc15':tf.Variable(tf.random_normal([3,3,512,512])),
    'wc16':tf.Variable(tf.random_normal([3,3,512,256])),
    
    'wd1':tf.Variable(tf.random_normal([4096,4096])),
    'wd2':tf.Variable(tf.random_normal([4096,4096])),
    'out':tf.Variable(tf.random_normal([4096,nn_classes])),
}

biases ={
    'bc1':tf.Variable(tf.zeros([64])),
    'bc2':tf.Variable(tf.zeros([64])),
    'bc3':tf.Variable(tf.zeros([128])),
    'bc4':tf.Variable(tf.zeros([128])),
    'bc5':tf.Variable(tf.zeros([256])),
    'bc6':tf.Variable(tf.zeros([256])),
    'bc7':tf.Variable(tf.zeros([256])),
    'bc8':tf.Variable(tf.zeros([256])),
    'bc9':tf.Variable(tf.zeros([512])),
    'bc10':tf.Variable(tf.zeros([512])),
    'bc11':tf.Variable(tf.zeros([512])),
    'bc12':tf.Variable(tf.zeros([512])),
    'bc13':tf.Variable(tf.zeros([512])),
    'bc14':tf.Variable(tf.zeros([512])),
    'bc15':tf.Variable(tf.zeros([512])),
    'bc16':tf.Variable(tf.zeros([256])),
    
    
    'bd1':tf.Variable(tf.zeros([4096])),
    'bd2':tf.Variable(tf.zeros([4096])),
    'out':tf.Variable(tf.zeros([nn_classes])),
}


卷积实现:

def convLevel(i,input,type):
    num = i
    out = conv2D('conv'+str(num),input,weights['wc'+str(num)],biases['bc'+str(num)])
    if  type=='p':
        out = maxPool2D('pool'+str(num),out, k=2) 
        out = norm('norm'+str(num),out, lsize=4)
    return out 


def VGG(x,weights,biases,dropout):
    x = tf.reshape(x,shape=[-1,28,28,1])


    input = x


    for i in range(16):
        i += 1
        if(i==2) or (i==4) or (i==12) : # 根据模型定义还需要更多的POOL化,但mnist图片大小不允许。
            input = convLevel(i,input,'p')
        else:
            input = convLevel(i,input,'c')


训练:

pred = VGG(x, weights, biases, keep_prob)
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=pred,labels=y))
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()
with tf.Session() as sess:
    sess.run(init)
    step = 1
    while step*batch_size < train_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})
        print(step*batch_size)
        if step % display_step == 0 :
           #loss,acc = sess.run([cost,accuracy],feed_dict={x:batch_x,y:batch_y,keep_prob=1.0})
           acc = sess.run(accuracy_, feed_dict={x: batch_x, y: batch_y, keep_prob: 1.})
            # 计算损失值
           
           loss = sess.run(cost, feed_dict={x: batch_x, y: batch_y, keep_prob: 1.})
           print("iter: "+str(step*batch_size)+"mini batch Loss="+"{:.6f}".format(loss)+",acc="+"{:6f}".format(acc))


        step += 1 
     
     
    print("training end!")  


最终效果:

训练10000次后:结果如下:

iter: 12288 mini batch Loss=5088409.500000,acc=0.578125

iter: 12800 mini batch Loss=4514274.000000,acc=0.601562

iter: 13312 mini batch Loss=4483454.500000,acc=0.648438

这种深度的模型可以考虑循环10万次以上。目前效果还不错,本人没有GPU,心痛笔记本的CPU,100%的CPU利用率,听到风扇响就不忍心再训练,本文也借鉴了alex网络实现,当然我也实现了这个网络模型。在MNIST数据上,ALEX由于层数较少,收敛更快,当然MNIST,用CNN足够了。



  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
VGG16是一个经典的卷积神经网络模型,通常用于图像分类任务。而MNIST是一个手写数字数据集,包含了60000个训练样本和10000个测试样本。在这里,我们将探讨如何使用VGG16模型来训练MNIST数据集。 首先,我们需要导入必要的库和数据集。 ```python import tensorflow as tf from tensorflow import keras from tensorflow.keras import layers (x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data() x_train = x_train.astype("float32") / 255.0 x_test = x_test.astype("float32") / 255.0 ``` 接下来,我们需要将MNIST数据集的输入形状转换为3D格式,以适应VGG16模型的输入要求。 ```python x_train = tf.expand_dims(x_train, -1) x_test = tf.expand_dims(x_test, -1) ``` 然后,我们可以定义VGG16模型并对其进行编译。我们将使用交叉熵损失函数和Adam优化器来训练模型。 ```python model = keras.Sequential( [ keras.Input(shape=(28, 28, 1)), layers.Conv2D(64, kernel_size=(3, 3), activation="relu", padding="same"), layers.Conv2D(64, kernel_size=(3, 3), activation="relu", padding="same"), layers.MaxPooling2D(pool_size=(2, 2)), layers.Conv2D(128, kernel_size=(3, 3), activation="relu", padding="same"), layers.Conv2D(128, kernel_size=(3, 3), activation="relu", padding="same"), layers.MaxPooling2D(pool_size=(2, 2)), layers.Conv2D(256, kernel_size=(3, 3), activation="relu", padding="same"), layers.Conv2D(256, kernel_size=(3, 3), activation="relu", padding="same"), layers.Conv2D(256, kernel_size=(3, 3), activation="relu", padding="same"), layers.MaxPooling2D(pool_size=(2, 2)), layers.Conv2D(512, kernel_size=(3, 3), activation="relu", padding="same"), layers.Conv2D(512, kernel_size=(3, 3), activation="relu", padding="same"), layers.Conv2D(512, kernel_size=(3, 3), activation="relu", padding="same"), layers.MaxPooling2D(pool_size=(2, 2)), layers.Conv2D(512, kernel_size=(3, 3), activation="relu", padding="same"), layers.Conv2D(512, kernel_size=(3, 3), activation="relu", padding="same"), layers.Conv2D(512, kernel_size=(3, 3), activation="relu", padding="same"), layers.MaxPooling2D(pool_size=(2, 2)), layers.Flatten(), layers.Dense(4096, activation="relu"), layers.Dense(4096, activation="relu"), layers.Dense(10, activation="softmax"), ] ) model.compile(loss="sparse_categorical_crossentropy", optimizer="adam", metrics=["accuracy"]) ``` 最后,我们可以使用训练对模型进行训练,并在测试上评估模型的性能。 ```python model.fit(x_train, y_train, batch_size=128, epochs=10, validation_split=0.1) test_scores = model.evaluate(x_test, y_test, verbose=2) print("Test loss:", test_scores[0]) print("Test accuracy:", test_scores[1]) ``` 希望这个例子可以帮助你理解如何使用VGG16模型训练MNIST数据集

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值