欧搏代理:经典卷积神经网络算法(3):VGG

admin 7天前 科技 55 1

 

VGG的实质是AlexNet结构的增强版,它将卷积层的深度提升到了19层,而且在2014年的ImageNet大赛中的定位问题中获得了亚军(冠军是GoogLeNet,将在下一篇博客中先容)。整个网络向人们证明了我们是可以用很小的卷积核取得很好地效果,条件是我们要把网络的层数加深,这也论证了我们要想提高整个神经网络的模子效果,一个较为有用的方式即是将它的深度加深,虽然盘算量会大大提高,然则整个庞大度也上升了,更能解决庞大的问题。虽然VGG网络已经降生好几年了,然则许多其他网络上效果并不是很好地情形下,VGG有时刻还能够施展它的优势,让人有意想不到的收获。

与AlexNet网络异常类似,VGG共有五个卷积层,而且每个卷积层之后都有一个池化层。那时在ImageNet大赛中,作者划分尝试了六种网络结构。这六种结构大致相同,只是层数差别,少则11层,多达19层。网络结构的输入是巨细为224*224的RGB图像,最终将分类效果输出。固然,在输入网络时,图片要举行预处理。

VGG网络相比AlexNet网络,在网络的深度以及宽度上做了一定的拓展,详细的卷积运算照样与AlexNet网络类似。我们主要说明一下VGG网络所做的改善。
第一点,由于许多研究者发现归一化层的效果并不是很好,而且占用了大量的盘算资源,以是在VGG网络中作者取消了归一化层;
第二点,VGG网络用了更小的3x3的卷积核,而两个延续的3x3的卷积核相当于5x5的感受野,由此类推,三个3x3的延续的卷积核也就相当于7x7的感受野。这样的转变使得参数目更小,节省了盘算资源,将资源留给后面的更深条理的网络。
第三点是VGG网络中的池化层特征池化核改为了2x2,而在AlexNet网络中池化核为3x3。
这三点改善无疑是使得整个参数运算量下降,这样我们在有限的盘算平台上能够获得更多的资源留给更深层的网络。由于层数较多,卷积核对照小,这样使得整个网络的特征提取效果很好。实在由于VGG的层数较多,以是盘算量照样相当大的,卷积层对照多成了它最显著的特点。另外,VGG网络的拓展性能对照突出,结构对照简练,以是它的迁徙性能对照好,迁徙到其他数据集的时刻泛化性能好。到现在为止,VGG网络还经常被用来提出特征。以是当现在许多较新的模子效果欠好时,使用VGG可能会解决这些问题。

In [5]:
import os
import tensorflow as tf
from tensorflow.keras import layers, optimizers, datasets, Sequential
import matplotlib.pyplot as plt
In [6]:
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
tf.random.set_seed(2345)
 

先来加载图像数据集。这里,我们使用tensorflow自带的cifar100数据集。

In [16]:
(x_train, y_train), (x_test, y_test) = datasets.cifar100.load_data()
 

查看数据大致情形:

In [17]:
print(x_train.shape, y_train.shape)
print(x_test.shape, y_test.shape)
 
(50000, 32, 32, 3) (50000, 1)
(10000, 32, 32, 3) (10000, 1)
In [18]:
index = 1
fig, axes = plt.subplots(4, 3, figsize=(8, 4), tight_layout=True)
for row in range(4):
    for col in range(3):
        axes[row, col].imshow(x_train[index])
        axes[row, col].axis('off')
        axes[row, col].set_title(y_train[index][0])
        index += 1
plt.show()
  In [13]:
y_train = tf.squeeze(y_train, axis=1)
y_test = tf.squeeze(y_test, axis=1)
In [7]:
def preprocess(x, y):
    x = tf.cast(x, dtype=tf.float32) / 255.  # 将每个像素值映射到[0, 1]内
    y = tf.cast(y, dtype=tf.float32)
    return x, y
 

将数据集用TensorFlow的dataset存储并打乱:

In [13]:
train_db = tf.data.Dataset.from_tensor_slices((x_train, y_train))
train_db = train_db.shuffle(1000).map(preprocess).batch(64)
test_db = tf.data.Dataset.from_tensor_slices((x_test, y_test))
test_db = test_db.shuffle(1000).map(preprocess).batch(64)
 

现在来建立卷积部门网络,共10个卷积层,每两层之间添加一层最大池化层。在设计卷积网络时,一样平常使核的数目保持增添,但每个核输出的特征图巨细降低或保持稳定。

 

在前面实现LeNet和AlexNet网络博客中,我们是直接使用模子的fit方式训练模子,在卷积网络与全毗邻网络的过渡部门通过TensorFlow的flatten层举行过渡,在本文中,为更好演示网络的各个细节,对这两个功效我们均手动实现。

In [14]:
conv_layers = [ # 5层卷积,每两层卷积后添加一层最大池化

    layers.Conv2D(64, kernel_size=[3,3],padding='same', activation=tf.nn.relu),  # 64是指核的数目,
    layers.Conv2D(64, kernel_size=[3,3],padding='same', activation=tf.nn.relu),  # same是指输入于输出保持相同size
    layers.MaxPool2D(pool_size=[2, 2], strides=2, padding='same'),
    
    layers.Conv2D(128, kernel_size=[3,3],padding='same', activation=tf.nn.relu),
    layers.Conv2D(128, kernel_size=[3,3],padding='same', activation=tf.nn.relu),
    layers.MaxPool2D(pool_size=[2, 2], strides=2, padding='same'),
    
    layers.Conv2D(256, kernel_size=[3,3],padding='same', activation=tf.nn.relu),
    layers.Conv2D(256, kernel_size=[3,3],padding='same', activation=tf.nn.relu),
    layers.MaxPool2D(pool_size=[2, 2], strides=2, padding='same'),
    
    layers.Conv2D(512, kernel_size=[3,3],padding='same', activation=tf.nn.relu),
    layers.Conv2D(512, kernel_size=[3,3],padding='same', activation=tf.nn.relu),
    layers.MaxPool2D(pool_size=[2, 2], strides=2, padding='same'),
    
    layers.Conv2D(512, kernel_size=[3,3],padding='same', activation=tf.nn.relu),
    layers.Conv2D(512, kernel_size=[3,3],padding='same', activation=tf.nn.relu),
    layers.MaxPool2D(pool_size=[2, 2], strides=2, padding='same')
]
 

如果我们输入网络中的图像巨细为32*32,包罗3通道,检测一下输出巨细:

In [15]:
conv_net = Sequential(conv_layers)
conv_net.build(input_shape=[None, 32, 32, 3])  # 指定输入
x = tf.random.normal([1, 32, 32, 3])  # 1是指输入一张图像,两个32是图像长宽,3是指3通道
out = conv_net(x)
out.shape
Out[15]:
TensorShape([1, 1, 1, 512])
 

可知,经由5层卷积核池化之后,最终的输出巨细为[1, 1, 1, 512],凭据这一信息,我们就可以进一步设计全毗邻网络。在设计全毗邻网络时需要注重,由于数据集图像有100个种别,以是全毗邻层中最后一层节点数目为100.

In [16]:
fc_layers = [  # 全毗邻层
    layers.Dense(256, activation=tf.nn.relu),
    layers.Dense(128, activation=tf.nn.relu),
    layers.Dense(100, activation=None)
]
 

指定输入全毗邻层数据巨细,并建立模子:

In [17]:
fc_net = Sequential(fc_layers)

fc_net.build(input_shape=[None, 512])
 

将卷积层和全毗邻层参数统一存储,利便后续利便后续更新:

In [18]:
variables = conv_net.trainable_variables + fc_net.trainable_variables
 

建立优化器:

In [19]:
optimizer = optimizers.Adam(lr=1e-4)
 

手动实现fit功效,举行模子训练。

In [28]:
for epoch in range(5):
    for step , (x, y) in enumerate(train_db):
        with tf.GradientTape() as tape:
            # 第一步, 将图像数据传入卷积层网络
            # [batch, 32, 32, 3] -->  [batch, 1, 1, 512]
            out = conv_net(x)
            # 第二步, 卷卷积层输出的特征图输出到全毗邻层网络
            # 需要先将特征图举行变形
            out = tf.reshape(out, [-1, 512])   # [batch, 1, 1, 512] --> [Batch, 512]
            # 全毗邻层:[batch, 512]  --> [b, 100]
            logits = fc_net(out)
            # 对输出举行独热编码:
            # y_onehot = tf.keras.one_hot(y, depth=100)  # 直接使用tf.one_hot()报错Could not find valid device for node.
            y_onehot = tf.keras.utils.to_categorical(y, num_classes=100)  # 以是使用这种方式举行独热编码
            # 盘算损失函数
            loss = tf.losses.categorical_crossentropy(y_onehot, logits, from_logits=True)
            loss = tf.reduce_mean(loss)  # 损失均值
            
        grads = tape.gradient(loss, variables)  # 对卷积层和全毗邻层参数举行求导
        optimizer.apply_gradients(zip(grads, variables))  # 更新参数
        if step % 100 == 0: # 每1000次流传输出一次
            print(epoch , step, 'loss:', float(loss))
    total_num = 0 
    total_correct = 0
    for x, y in test_db:
        out = conv_net(x)
        out = tf.reshape(out, [-1, 512])
        logits = fc_net(out)
        prob = tf.nn.softmax(logits, axis=1)
        pred = tf.argmax(prob, axis=1)
        pred = tf.cast(pred, dtype=tf.int32)
        y = tf.cast(y, dtype=tf.int32)
        correct = tf.cast(tf.equal(pred , y), dtype=tf.int32)
        correct = tf.reduce_sum(correct)
        
        total_num += x.shape[0]
        total_correct += int(correct)
    acc = total_correct / total_num
    print(epoch, 'acc:', acc)
        
 
0 0 loss: 3.2746524810791016
0 100 loss: 3.1227006912231445
0 200 loss: 3.3354835510253906
0 300 loss: 3.5577585697174072
0 400 loss: 3.4442076683044434
0 500 loss: 3.5540578365325928
0 600 loss: 2.993718385696411
0 700 loss: 3.398216724395752
0 acc: 0.2156
1 0 loss: 3.2784264087677
1 100 loss: 2.915174961090088
1 200 loss: 3.1731386184692383
1 300 loss: 2.9105772972106934
1 400 loss: 2.889545202255249
1 500 loss: 3.0817737579345703
1 600 loss: 2.8999242782592773
1 700 loss: 2.847750186920166
1 acc: 0.2577
2 0 loss: 3.0487632751464844
2 100 loss: 2.961989164352417
2 200 loss: 2.810255527496338
2 300 loss: 2.921875476837158
2 400 loss: 3.0022480487823486
2 500 loss: 2.8648478984832764
2 600 loss: 2.313401222229004
2 700 loss: 2.9197773933410645
2 acc: 0.2714
3 0 loss: 3.2561397552490234
3 100 loss: 2.6284666061401367
3 200 loss: 2.611253499984741
3 300 loss: 2.6300625801086426
3 400 loss: 2.8262720108032227
3 500 loss: 2.4057717323303223
3 600 loss: 2.365994691848755
3 700 loss: 2.552517890930176
3 acc: 0.3038
4 0 loss: 2.8142364025115967
4 100 loss: 2.7545413970947266
4 200 loss: 2.5179195404052734
4 300 loss: 2.093433380126953
4 400 loss: 2.763005256652832
4 500 loss: 2.2059311866760254
4 600 loss: 2.128242015838623
4 700 loss: 2.2914538383483887
4 acc: 0.3382
 

上述训练经由了5次迭代,准确率到达33.82%,增添迭代次数可进一步提高准确率。对比上篇博客的AlexNet网络,我们发现VGG网络显著收敛速率更快,模子西能更佳。

参考:

https://baijiahao.baidu.com/s?id=1636567480736287260&wfr=spider&for=pc

,

欧博网址

www.cx11gw.cn欢迎进入欧博网址(Allbet Gaming),欧博网址开放会员注册、代理开户、电脑客户端下载、苹果安卓下载等业务。

皇冠体育声明:该文看法仅代表作者自己,与本平台无关。转载请注明:欧搏代理:经典卷积神经网络算法(3):VGG

网友评论

  • (*)

最新评论

  • 皇冠APP下载 2020-09-14 00:03:06 回复

    佳木斯新闻网1佳木斯新闻网是佳木斯日报旗下主办的新闻网,专业报道最新最热的佳木斯新闻,真实反映每时每刻,内容全面,领域多方位,包括社会新闻、军事新闻、经济新闻以及各种本地大事记,这里也有最专业的时政评论员权威解读新闻要点难点,让您足不出户知晓周边乃至天下事,佳木斯日报新闻网还积极配合党建工作,助力我国政治繁荣,目前已经成为东北地区知名度较高的重点新闻网站。我沙发没了

    1

文章归档

站点信息

  • 文章总数:772
  • 页面总数:0
  • 分类总数:8
  • 标签总数:1234
  • 评论总数:384
  • 浏览总数:24911