一个项目学会tensorflow2.0

优化:

1.使用数据增强技术。

2.使用数据生成器提高训练速度。

3.调节超参数,提高模型精度。

4.使用VGG技术迁移学习,提高训练速度。



目标

  • 算法应用

    • 熟练掌握TensorFlow框架使用
    • 掌握神经网络图像相关案例

1.训练的时候读取本地图片以及类别

train_generator = ImageDataGenerator()

  • 生产图片的批次张量值并且提供数据增强功能
  • rescale=1.0 / 255,:标准化
  • zca_whitening=False: # zca白化的作用是针对图片进行PCA降维操作,减少图片的冗余信息
  • rotation_range=20:默认0, 旋转角度,在这个角度范围随机生成一个值
  • width_shift_range=0.2,:默认0,水平平移
  • height_shift_range=0.2:默认0, 垂直平移
  • shear_range=0.2:# 平移变换
  • zoom_range=0.2:
  • horizontal_flip=True:水平翻转

使用train_generator.flow_from_directory()

  • directory=path,# 读取目录

  • target_size=(h,w),# 目标形状

  • batch_size=size,# 批数量大小

  • class_mode='binary', # 目标值格式,One of "categorical", "binary", "sparse",

    • "categorical" :2D one-hot encoded labels
    • "binary" will be 1D binary labels
  • shuffle=True

2.思路和步骤

  • 读取本地的图片数据以及类别
    • keras.preprocessing.image import ImageDataGenerator提供了读取转换功能
  • 模型的结构修改(添加我们自定的分类层)
  • freeze掉原始VGG模型
  • 编译以及训练和保存模型方式
  • 输入数据进行预测

3.模型设计

VGG模型的修改添加全连接层

一个GlobalAveragePooling2D + 两个全连接层

  • 在图像分类任务中,模型经过最后CNN层后的尺寸为[bath_size, img_width, img_height, channels],通常的做法是:接一个flatten layer,将尺寸变为[batch_size, w channels]再至少接一个FC layer,这样做的最大问题是:模型参数多,且容易过拟合。

  • 利用pooling layer来替代最后的FC layer

4.编译和训练

 def compile(self, model):

        model.compile(optimizer=keras.optimizers.Adam(),
                      loss=keras.losses.sparse_categorical_crossentropy,
                      metrics=['accuracy'])

5.训练和回调函数callbacks

keras.callbacks.ModelCheckpoint(filepath, monitor='val_loss', verbose=0, save_best_only=False, save_weights_only=False, mode='auto', period=1)

参数

  • filepath: 字符串,保存模型的路径, 如果 filepath 是 weights.{epoch:02d}-{val_loss:.2f}.hdf5, 那么模型被保存的的文件名就会有训练轮数和验证损失。
  • monitor: 被监测的数据,损失函数或者准确率
  • verbose: 详细信息模式,0 或者 1 ,输出结果打印
  • save_best_only: 如果 save_best_only=True, 被监测数据的最佳模型就不会被覆盖,只保留最好的
  • mode: {auto, min, max} 的其中之一。 如果 save_best_only=True,那么是否覆盖保存文件的决定就取决于被监测数据的最大或者最小值。 对于 val_acc,模式就会是 max,而对于 val_loss,模式就需要是 min,等等。 在 auto 模式中,方向会自动从被监测的数据的名字中判断出来。
  • save_weights_only: 如果 True,那么只有模型的权重会被保存 (model.save_weights(filepath)), 否则的话,整个模型会被保存 (model.save(filepath))。
  • period: 每个检查点之间的间隔(训练轮数)。

6.进行预测

预测的步骤就是读取图片以及处理到模型中预测,加载我们训练的模型

7.训练记录如下

_________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         [(None, None, None, 3)]   0         
_________________________________________________________________
block1_conv1 (Conv2D)        (None, None, None, 64)    1792      
_________________________________________________________________
block1_conv2 (Conv2D)        (None, None, None, 64)    36928     
_________________________________________________________________
block1_pool (MaxPooling2D)   (None, None, None, 64)    0         
_________________________________________________________________
block2_conv1 (Conv2D)        (None, None, None, 128)   73856     
_________________________________________________________________
block2_conv2 (Conv2D)        (None, None, None, 128)   147584    
_________________________________________________________________
block2_pool (MaxPooling2D)   (None, None, None, 128)   0         
_________________________________________________________________
block3_conv1 (Conv2D)        (None, None, None, 256)   295168    
_________________________________________________________________
block3_conv2 (Conv2D)        (None, None, None, 256)   590080    
_________________________________________________________________
block3_conv3 (Conv2D)        (None, None, None, 256)   590080    
_________________________________________________________________
block3_pool (MaxPooling2D)   (None, None, None, 256)   0         
_________________________________________________________________
block4_conv1 (Conv2D)        (None, None, None, 512)   1180160   
_________________________________________________________________
block4_conv2 (Conv2D)        (None, None, None, 512)   2359808   
_________________________________________________________________
block4_conv3 (Conv2D)        (None, None, None, 512)   2359808   
_________________________________________________________________
block4_pool (MaxPooling2D)   (None, None, None, 512)   0         
_________________________________________________________________
block5_conv1 (Conv2D)        (None, None, None, 512)   2359808   
_________________________________________________________________
block5_conv2 (Conv2D)        (None, None, None, 512)   2359808   
_________________________________________________________________
block5_conv3 (Conv2D)        (None, None, None, 512)   2359808   
_________________________________________________________________
block5_pool (MaxPooling2D)   (None, None, None, 512)   0         
_________________________________________________________________
global_average_pooling2d (Gl (None, 512)               0         
_________________________________________________________________
dense (Dense)                (None, 1024)              525312    
_________________________________________________________________
dense_1 (Dense)              (None, 5)                 5125      
=================================================================
Total params: 15,245,125
Trainable params: 15,245,125
Non-trainable params: 0
_________________________________________________________________
None
WARNING:tensorflow:`period` argument is deprecated. Please use `save_freq` to specify the frequency in number of samples seen.
Epoch 1/5
2022-01-11 19:45:50.379409: W tensorflow/core/framework/cpu_allocator_impl.cc:81] Allocation of 205520896 exceeds 10% of system memory.
2022-01-11 19:45:50.889438: W tensorflow/core/framework/cpu_allocator_impl.cc:81] Allocation of 205520896 exceeds 10% of system memory.

 1/25 [>.............................] - ETA: 7:36 - loss: 1.8611 - acc: 0.37502022-01-11 19:46:07.844408: W tensorflow/core/framework/cpu_allocator_impl.cc:81] Allocation of 205520896 exceeds 10% of system memory.
2022-01-11 19:46:08.092422: W tensorflow/core/framework/cpu_allocator_impl.cc:81] Allocation of 205520896 exceeds 10% of system memory.

 2/25 [=>............................] - ETA: 6:24 - loss: 1.6121 - acc: 0.50002022-01-11 19:46:22.274233: W tensorflow/core/framework/cpu_allocator_impl.cc:81] Allocation of 205520896 exceeds 10% of system memory.

 3/25 [==>...........................] - ETA: 5:50 - loss: 1.6170 - acc: 0.4583
 4/25 [===>..........................] - ETA: 5:26 - loss: 1.5825 - acc: 0.5000
 5/25 [=====>........................] - ETA: 5:06 - loss: 1.5714 - acc: 0.5125
 6/25 [======>.......................] - ETA: 4:48 - loss: 1.5080 - acc: 0.5104
 7/25 [=======>......................] - ETA: 4:31 - loss: 1.4150 - acc: 0.5536
 8/25 [========>.....................] - ETA: 4:14 - loss: 1.3916 - acc: 0.5312
 9/25 [=========>....................] - ETA: 3:58 - loss: 1.3366 - acc: 0.5417
10/25 [===========>..................] - ETA: 3:43 - loss: 1.2681 - acc: 0.5750
11/25 [============>.................] - ETA: 3:27 - loss: 1.2320 - acc: 0.5795
12/25 [=============>................] - ETA: 3:12 - loss: 1.1886 - acc: 0.5833
13/25 [==============>...............] - ETA: 2:57 - loss: 1.1473 - acc: 0.6010
14/25 [===============>..............] - ETA: 2:42 - loss: 1.1124 - acc: 0.6205
15/25 [=================>............] - ETA: 2:27 - loss: 1.0875 - acc: 0.6250
16/25 [==================>...........] - ETA: 2:12 - loss: 1.0576 - acc: 0.6367
17/25 [===================>..........] - ETA: 1:57 - loss: 1.0182 - acc: 0.6507
18/25 [====================>.........] - ETA: 1:42 - loss: 0.9929 - acc: 0.6667
19/25 [=====================>........] - ETA: 1:27 - loss: 0.9637 - acc: 0.6809
20/25 [=======================>......] - ETA: 1:13 - loss: 0.9327 - acc: 0.6969
21/25 [========================>.....] - ETA: 58s - loss: 0.9055 - acc: 0.7083 
22/25 [=========================>....] - ETA: 43s - loss: 0.8836 - acc: 0.7159
23/25 [==========================>...] - ETA: 29s - loss: 0.8649 - acc: 0.7201
24/25 [===========================>..] - ETA: 14s - loss: 0.8540 - acc: 0.7214Epoch 1/5

 1/25 [>.............................] - ETA: 6:08 - loss: 0.3627 - acc: 0.9375
 2/25 [=>............................] - ETA: 5:40 - loss: 0.3628 - acc: 0.9062
 3/25 [==>...........................] - ETA: 5:21 - loss: 0.3862 - acc: 0.8750
 4/25 [===>..........................] - ETA: 5:15 - loss: 0.3624 - acc: 0.8750
 5/25 [=====>........................] - ETA: 4:57 - loss: 0.3307 - acc: 0.9000
 6/25 [======>.......................] - ETA: 4:41 - loss: 0.3185 - acc: 0.9062
 7/25 [=======>......................] - ETA: 3:59 - loss: 0.4027 - acc: 0.8800
25/25 [==============================] - 459s 18s/step - loss: 0.8366 - acc: 0.7225 - val_loss: 0.4027 - val_acc: 0.8800
Epoch 2/5

 1/25 [>.............................] - ETA: 5:49 - loss: 0.2977 - acc: 0.8750
 2/25 [=>............................] - ETA: 5:33 - loss: 0.2384 - acc: 0.9375
 3/25 [==>...........................] - ETA: 5:18 - loss: 0.2150 - acc: 0.9583
 4/25 [===>..........................] - ETA: 5:03 - loss: 0.2440 - acc: 0.9375
 5/25 [=====>........................] - ETA: 4:48 - loss: 0.2576 - acc: 0.9250
 6/25 [======>.......................] - ETA: 4:34 - loss: 0.2808 - acc: 0.8958
 7/25 [=======>......................] - ETA: 4:20 - loss: 0.2706 - acc: 0.9107
 8/25 [========>.....................] - ETA: 4:05 - loss: 0.2600 - acc: 0.9141
 9/25 [=========>....................] - ETA: 3:51 - loss: 0.2458 - acc: 0.9236
10/25 [===========>..................] - ETA: 3:36 - loss: 0.2523 - acc: 0.9312
11/25 [============>.................] - ETA: 3:22 - loss: 0.2505 - acc: 0.9318
12/25 [=============>................] - ETA: 3:09 - loss: 0.2468 - acc: 0.9375
13/25 [==============>...............] - ETA: 2:56 - loss: 0.2361 - acc: 0.9423
14/25 [===============>..............] - ETA: 2:41 - loss: 0.2375 - acc: 0.9420
15/25 [=================>............] - ETA: 2:28 - loss: 0.2371 - acc: 0.9458
16/25 [==================>...........] - ETA: 2:14 - loss: 0.2274 - acc: 0.9492
17/25 [===================>..........] - ETA: 2:00 - loss: 0.2229 - acc: 0.9522
18/25 [====================>.........] - ETA: 1:45 - loss: 0.2139 - acc: 0.9549
19/25 [=====================>........] - ETA: 1:30 - loss: 0.2122 - acc: 0.9539
20/25 [=======================>......] - ETA: 1:15 - loss: 0.2084 - acc: 0.9563
21/25 [========================>.....] - ETA: 1:00 - loss: 0.2046 - acc: 0.9583
22/25 [=========================>....] - ETA: 45s - loss: 0.2091 - acc: 0.9489 
23/25 [==========================>...] - ETA: 30s - loss: 0.2055 - acc: 0.9511
24/25 [===========================>..] - ETA: 15s - loss: 0.2005 - acc: 0.9531Epoch 1/5

 1/25 [>.............................] - ETA: 6:42 - loss: 0.1403 - acc: 1.0000
 2/25 [=>............................] - ETA: 6:10 - loss: 0.1468 - acc: 0.9688
 3/25 [==>...........................] - ETA: 5:48 - loss: 0.2241 - acc: 0.9167
 4/25 [===>..........................] - ETA: 5:29 - loss: 0.2017 - acc: 0.9375
 5/25 [=====>........................] - ETA: 5:09 - loss: 0.1962 - acc: 0.9250
 6/25 [======>.......................] - ETA: 4:50 - loss: 0.1872 - acc: 0.9375
 7/25 [=======>......................] - ETA: 4:06 - loss: 0.1914 - acc: 0.9400
25/25 [==============================] - 475s 19s/step - loss: 0.1960 - acc: 0.9550 - val_loss: 0.1914 - val_acc: 0.9400
Epoch 3/5

 1/25 [>.............................] - ETA: 5:50 - loss: 0.2164 - acc: 0.9375
 2/25 [=>............................] - ETA: 5:34 - loss: 0.1589 - acc: 0.9688
 3/25 [==>...........................] - ETA: 5:20 - loss: 0.1342 - acc: 0.9792
 4/25 [===>..........................] - ETA: 5:05 - loss: 0.1308 - acc: 0.9844
 5/25 [=====>........................] - ETA: 4:51 - loss: 0.1385 - acc: 0.9750
 6/25 [======>.......................] - ETA: 4:37 - loss: 0.1266 - acc: 0.9792
 7/25 [=======>......................] - ETA: 4:23 - loss: 0.1370 - acc: 0.9732
 8/25 [========>.....................] - ETA: 4:09 - loss: 0.1324 - acc: 0.9766
 9/25 [=========>....................] - ETA: 3:54 - loss: 0.1235 - acc: 0.9792
10/25 [===========>..................] - ETA: 3:40 - loss: 0.1169 - acc: 0.9812
11/25 [============>.................] - ETA: 3:26 - loss: 0.1161 - acc: 0.9830
12/25 [=============>................] - ETA: 3:11 - loss: 0.1118 - acc: 0.9844
13/25 [==============>...............] - ETA: 2:56 - loss: 0.1084 - acc: 0.9856
14/25 [===============>..............] - ETA: 2:42 - loss: 0.1051 - acc: 0.9866
15/25 [=================>............] - ETA: 2:27 - loss: 0.1039 - acc: 0.9875
16/25 [==================>...........] - ETA: 2:12 - loss: 0.1010 - acc: 0.9883
17/25 [===================>..........] - ETA: 1:57 - loss: 0.1011 - acc: 0.9890
18/25 [====================>.........] - ETA: 1:43 - loss: 0.1008 - acc: 0.9896
19/25 [=====================>........] - ETA: 1:28 - loss: 0.0988 - acc: 0.9901
20/25 [=======================>......] - ETA: 1:13 - loss: 0.0960 - acc: 0.9906
21/25 [========================>.....] - ETA: 59s - loss: 0.0936 - acc: 0.9911 
22/25 [=========================>....] - ETA: 44s - loss: 0.0913 - acc: 0.9915
23/25 [==========================>...] - ETA: 29s - loss: 0.0938 - acc: 0.9891
24/25 [===========================>..] - ETA: 14s - loss: 0.0919 - acc: 0.9896Epoch 1/5

 1/25 [>.............................] - ETA: 6:25 - loss: 0.1734 - acc: 0.9375
 2/25 [=>............................] - ETA: 5:55 - loss: 0.1461 - acc: 0.9375
 3/25 [==>...........................] - ETA: 5:35 - loss: 0.2080 - acc: 0.8958
 4/25 [===>..........................] - ETA: 5:18 - loss: 0.1843 - acc: 0.9219
 5/25 [=====>........................] - ETA: 5:04 - loss: 0.1667 - acc: 0.9250
 6/25 [======>.......................] - ETA: 4:48 - loss: 0.1599 - acc: 0.9271
 7/25 [=======>......................] - ETA: 4:05 - loss: 0.1575 - acc: 0.9300
25/25 [==============================] - 467s 19s/step - loss: 0.0898 - acc: 0.9900 - val_loss: 0.1575 - val_acc: 0.9300
Epoch 4/5

 1/25 [>.............................] - ETA: 6:11 - loss: 0.1034 - acc: 1.0000
 2/25 [=>............................] - ETA: 5:50 - loss: 0.0808 - acc: 1.0000
 3/25 [==>...........................] - ETA: 5:36 - loss: 0.0719 - acc: 1.0000
 4/25 [===>..........................] - ETA: 5:31 - loss: 0.0739 - acc: 0.9844
 5/25 [=====>........................] - ETA: 5:19 - loss: 0.0667 - acc: 0.9875
 6/25 [======>.......................] - ETA: 5:02 - loss: 0.0652 - acc: 0.9896
 7/25 [=======>......................] - ETA: 4:45 - loss: 0.0609 - acc: 0.9911
 8/25 [========>.....................] - ETA: 4:29 - loss: 0.0631 - acc: 0.9922
 9/25 [=========>....................] - ETA: 4:13 - loss: 0.0636 - acc: 0.9931
10/25 [===========>..................] - ETA: 3:58 - loss: 0.0607 - acc: 0.9937
11/25 [============>.................] - ETA: 3:44 - loss: 0.0611 - acc: 0.9943
12/25 [=============>................] - ETA: 3:29 - loss: 0.0587 - acc: 0.9948
13/25 [==============>...............] - ETA: 3:13 - loss: 0.0558 - acc: 0.9952
14/25 [===============>..............] - ETA: 2:57 - loss: 0.0545 - acc: 0.9955
15/25 [=================>............] - ETA: 2:41 - loss: 0.0551 - acc: 0.9958
16/25 [==================>...........] - ETA: 2:24 - loss: 0.0529 - acc: 0.9961
17/25 [===================>..........] - ETA: 2:08 - loss: 0.0541 - acc: 0.9963
18/25 [====================>.........] - ETA: 1:52 - loss: 0.0521 - acc: 0.9965
19/25 [=====================>........] - ETA: 1:36 - loss: 0.0502 - acc: 0.9967
20/25 [=======================>......] - ETA: 1:20 - loss: 0.0513 - acc: 0.9969
21/25 [========================>.....] - ETA: 1:04 - loss: 0.0513 - acc: 0.9970
22/25 [=========================>....] - ETA: 1:10 - loss: 0.0500 - acc: 0.9972
23/25 [==========================>...] - ETA: 46s - loss: 0.0504 - acc: 0.9973 
24/25 [===========================>..] - ETA: 23s - loss: 0.0495 - acc: 0.9974
 

代码如下:

import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.applications.vgg16 import VGG16, preprocess_input
import numpy as np
import os
os.environ["TF_CPP_MIN_LOG_LEVEL"] = "2"


class TransferModel(object):
    """VGG迁移学习做5个类别图片识别
    """
    def __init__(self):
        # 初始化训练集和测试集的迭代器
        self.train_generator = ImageDataGenerator(rescale=1.0 / 255.0,
                                                  shear_range=0.2,
                                                  zoom_range=0.2,
                                                  horizontal_flip=True)

        self.test_generator = ImageDataGenerator(rescale=1.0 / 255.0)

        # 数据目录
        self.train_dir = "./data/train"
        self.test_dir = "./data/test"

        # 定义输入数据的大小和批次大小
        self.image_size = (224, 224)
        self.batch_size = 16

        # 初始化VGG基础模型,
        self.base_model = VGG16(weights='imagenet', include_top=False)

        self.label_dict = {
           
            '0': 'elephants',
            '1': 'flowers',
            '2': 'horse'
        }

    def get_local_data(self):
        """读取本地的图片数据以及类别标签
        :return:
        """
        # 1、datagen.flow_from_directory
        train_gen = self.train_generator.flow_from_directory(self.train_dir,
                                                             target_size=self.image_size,
                                                             batch_size=self.batch_size,
                                                             class_mode='binary',
                                                             shuffle=True)

        test_gen = self.train_generator.flow_from_directory(self.test_dir,
                                                             target_size=self.image_size,
                                                             batch_size=self.batch_size,
                                                             class_mode='binary',
                                                             shuffle=True)

        return train_gen, test_gen

    def refine_base_model(self):
        """
        修改VGG的模型
        :return: 新的迁移学习模型
        """
        # 1、获取VGG模型的输出,不包含原有模型的top结构
        x = self.base_model.outputs[0]

        x = tf.keras.layers.GlobalAveragePooling2D()(x)

        # 两个全连接层
        x = tf.keras.layers.Dense(1024, activation=tf.nn.relu)(x)
        y_predict = tf.keras.layers.Dense(5, activation=tf.nn.softmax)(x)

  
        transfer_model = tf.keras.models.Model(inputs=self.base_model.inputs, outputs=y_predict)

        return transfer_model

    def freeze_vgg_model(self):
        """
        冻结VGG的前面卷积结构,不参与训练
        :return:
        """
        # 循环获取base_model当中的层
        for layer in self.base_model.layers:
            layer.trainable = False

        return None

    def compile(self, model):
        """
        编译模型,指定优化器损失计算方式,准确率衡量
        :return:
        """
        model.compile(optimizer=tf.keras.optimizers.Adam(),
                      loss=tf.keras.losses.sparse_categorical_crossentropy,
                      metrics=['accuracy'])
        return None

    def fit_generator(self, model, train_gen, test_gen):
        """进行模型训练
        :param model:
        :param train_gen:
        :param test_gen:
        :return:
        """
        modelckpt = tf.keras.callbacks.ModelCheckpoint('./ckpt/transfer_{epoch:02d}-{acc:.2f}.h5',
                                                       monitor='accuracy',
                                                       save_best_only=False,
                                                       save_weights_only=False,
                                                       mode='auto',
                                                       period=1)

        h = model.fit_generator(train_gen, epochs=5, validation_data=test_gen, callbacks=[modelckpt])
        k = h.history()
        print('ooo')


        return None

    def predict(self, model):
        """预测输入图片的类别
        :return:
        """
    
        model.load_weights("./ckpt/transfer_01-0.82.h5")

        # 读取图片处理图片数据,形状,数据归一化
        image = tf.io.read_file("./data/test/dinosaurs/402.jpg")
        image_decoded = tf.image.decode_jpeg(image)
        image_resized = tf.image.resize(image_decoded, [224, 224]) / 255.0
     
        img = tf.reshape(image_resized, (1, image_resized.shape[0], image_resized.shape[1], image_resized.shape[2]))
        print("修改之后的形状:", img.shape)

        # 3、输入数据做预测
        y_predict = model.predict(img)

        index = np.argmax(y_predict, axis=1)
        print('=====', index)
        print('-=-=-=', index[0])
        print('-=-=-=', type(index[0]))
        print('-=-=-=', type(str(index[0])))

        print(self.label_dict[str(index[0])])

        return None


if __name__ == '__main__':

    tm = TransferModel()
  
    train_gen, test_gen = tm.get_local_data()
    print(train_gen, test_gen)
    
    # 模型的compile和训练
    model = tm.refine_base_model()
    print(model.summary())
    tm.freeze_vgg_model()
    tm.compile(model)
    tm.fit_generator(model, train_gen, test_gen)


   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值