日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

【神经网络】(4) 卷积神经网络(CNN),自定义网络,案例:彩色图像10分类

發布時間:2023/11/27 生活经验 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【神经网络】(4) 卷积神经网络(CNN),自定义网络,案例:彩色图像10分类 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

各位同學大家好,今天和大家分享一下TensorFlow2.0中如何使用函數方法自定義卷積神經網絡。

1. 導入數據

獲取系統自帶的10分類圖像數據,50k張用于訓練,10k張用于測試。

# 10分類卷積神經網絡
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import Sequential,optimizers,layers,datasets#(1)數據獲取
(x,y), (x_test, y_test) = datasets.cifar10.load_data()# 查看數據
print('x.shape:',x.shape,'y.shape:',y.shape)
print('x_test.shape:',x_test.shape,'y_test.shape:',y_test.shape)
print('y[:5]:',y[:5])
# x.shape: (50000, 32, 32, 3) y.shape: (50000, 1)
# x_test.shape: (10000, 32, 32, 3) y_test.shape: (10000, 1)#(2)圖像可視化
import matplotlib.pyplot as plt
for i in range(10):plt.subplot(2,5,i+1)plt.imshow(x[i])plt.xticks([])plt.yticks([])
plt.show()


2. 數據預處理

將圖像的每個像素值從[0,255]映射到[-1,1]之間,由于目標值y的shape為[b,1]需要把shape為1的軸擠壓掉tf.squeeze(),留下分類數值。對所有的訓練和測試數據集重新洗牌.shuffle(),但不打亂x和y之間的對應關系。每次迭代從數據集中取出128個樣本,.batch(128)

#(3)數據預處理
def processing(x,y):x = 2 * tf.cast(x, tf.float32) / 255.0 - 1  # [-1,1]y = tf.cast(y, tf.int32)return(x,y)# 構造訓練集數據集
y = tf.squeeze(y, axis=1)  # 擠壓掉shape=1的軸
train_ds = tf.data.Dataset.from_tensor_slices((x,y))
train_ds = train_ds.map(processing).shuffle(10000).batch(128) # 打亂數據集,每次迭代取128個數據# 構造測試集數據集,不需要onehot編碼,需要和預測結果比較
y_test = tf.squeeze(y_test, axis=1) 
test_ds = tf.data.Dataset.from_tensor_slices((x_test,y_test))
test_ds = test_ds.map(processing).shuffle(10000).batch(128) # 構造迭代器,查看劃分是否正確
sample = next(iter(train_ds)) # 每次運行從數據集中取出一組xy
print('x_batch:', sample[0].shape, 'y_batch:', sample[1].shape)
# x_batch: (64, 128, 128, 3) y_batch: (64, 3)

3. 構造網絡

使用函數方法自定義網絡各層,layers.BatchNormalization()為batchnorm層,在把輸入送入至非線性函數之前,能有效的將數據控制在一定的范圍內,使網絡更穩定,收斂更快。如果使用該層,訓練集和測試集的使用的方法不同,訓練時需要指定net(x, training=True)BN層的參數在正反向傳播過程中會被優化更新測試時指定net(x, training=False)。BN層的參數在正反向傳播過程中不會被更新。

#(4)網絡構造
# 自定義網絡層
def CNN(classes, input_shape):# 輸入層inputs = tf.keras.Input(shape=input_shape)# 卷積層x = layers.Conv2D(32, kernel_size=(3,3), strides=1, kernel_regularizer=keras.regularizers.l2(0.001), padding='same', activation='relu')(inputs)x = layers.Conv2D(32, kernel_size=(3,3), strides=1, padding='same')(x)# BN層x = layers.BatchNormalization()(x)# relu層x = layers.Activation('relu')(x)    # 池化層x = layers.MaxPool2D(pool_size=(2,2), strides=2, padding='same')(x)# unit2x = layers.Conv2D(64, kernel_size=(3,3), strides=1, kernel_regularizer=keras.regularizers.l2(0.001), padding='same', activation='relu')(x)x = layers.Conv2D(64, kernel_size=(3,3), strides=1, padding='same')(x)# BN層x = layers.BatchNormalization()(x)# relu層x = layers.Activation('relu')(x)    # 池化層x = layers.MaxPool2D(pool_size=(2,2), strides=2, padding='same')(x)# Flatten層 連接卷積層和全連接層x = layers.Flatten()(x)# 全連接層x = layers.Dense(128, activation='relu')(x)# Dropout層x = layers.Dropout(0.2)(x)    # 全連接層x = layers.Dense(64, activation='relu')(x)# Dropout層x = layers.Dropout(0.2)(x)# logits層,不轉為概率outputs = layers.Dense(classes)(x)# 構建網絡model = keras.Model(inputs=inputs, outputs=outputs)# 返回網絡結構return model# 傳入函數所需參數
model = CNN(10, (32, 32, 3))  # 指定10個分類,輸入的一張圖片的shape為(32,32,3)# 查看網絡結構
model.summary()# 指定優化器
optimizer = optimizers.Adam(lr=0.0001,  beta_1=0.9, beta_2=0.99)

?網絡結構如下圖所示,param代表每一層參數個數

Model: "model"
_________________________________________________________________Layer (type)                Output Shape              Param #   
=================================================================input_1 (InputLayer)        [(None, 32, 32, 3)]       0         conv2d (Conv2D)             (None, 32, 32, 32)        896       conv2d_1 (Conv2D)           (None, 32, 32, 32)        9248      batch_normalization (BatchN  (None, 32, 32, 32)       128       ormalization)                                                   activation (Activation)     (None, 32, 32, 32)        0         max_pooling2d (MaxPooling2D  (None, 16, 16, 32)       0         )                                                               conv2d_2 (Conv2D)           (None, 16, 16, 64)        18496     conv2d_3 (Conv2D)           (None, 16, 16, 64)        36928     batch_normalization_1 (Batc  (None, 16, 16, 64)       256       hNormalization)                                                 activation_1 (Activation)   (None, 16, 16, 64)        0         max_pooling2d_1 (MaxPooling  (None, 8, 8, 64)         0         2D)                                                             flatten (Flatten)           (None, 4096)              0         dense (Dense)               (None, 128)               524416    dropout (Dropout)           (None, 128)               0         dense_1 (Dense)             (None, 64)                8256      dropout_1 (Dropout)         (None, 64)                0         dense_2 (Dense)             (None, 10)                650       =================================================================
Total params: 599,274
Trainable params: 599,082
Non-trainable params: 192
_________________________________________________________________

4. 網絡訓練

為了得到和model.fit()一樣的效果,訓練過程和測試過程都計算一下損失和準確率,并將每一次迭代的結果保存下來。指定model(x, trainin=True)更新BN層參數。計算交叉熵損失時,categorical_crossentropy(y, logits, from_logits=True)logits為每張圖片屬于各個分類的實數值,指定from_logits=Truelogits會自動經過softmax函數變成概率再和真實值y比較,提高了網絡的穩定性。

# 保存每次循環的損失和準確率
train_loss_list = []
train_acc_list = []
test_loss_list = []
test_acc_list = []# 大循環
for epochs in range(10):  # 循環10次print('---------------')print('epochs:', epochs)#(5)網絡訓練total_sum = 0total_correct = 0total_loss = 0    for step, (x,y) in enumerate(train_ds):# 梯度跟蹤with tf.GradientTape() as tape:# 前行傳播,[b,32,32,3]=>[b,10]logits = model(x, trainin=True)  # 得到logits層輸出后的10分類數值# 計算準確率# 將logits層輸出結果轉概率prob = tf.nn.softmax(logits, axis=1)# 找到概率最大值對應的索引predict = tf.argmax(prob, axis=1, output_type=tf.int32)# 預測值和真實值是否相同correct = tf.cast(tf.equal(predict, y), tf.int32)# 計算預測對了幾個correct_sum = tf.reduce_sum(correct)# 計算總個數total_correct += correct_sum  # 總預測對了幾個total_sum += x.shape[0]  # 總共有多少參與# 計算損失y = tf.one_hot(y, depth=10)  # 真實值y是onehot編碼后的# 計算交叉熵損失CE = tf.losses.categorical_crossentropy(y, logits, from_logits=True)# 計算每個batch的平均損失loss = tf.reduce_mean(CE)# 記錄batch總損失loss_sum = tf.reduce_sum(CE)total_loss += loss_sum# 梯度計算grads = tape.gradient(loss, model.trainable_variables)  # 對所有的權重和偏置計算梯度# 更新梯度optimizer.apply_gradients(zip(grads, model.trainable_variables))# 每100個batch打印一次損失if step%100 == 0:print('step:', step, 'loss:', loss.numpy())# 保存訓練的準確率和損失# 計算每次循環的準確率train_acc = total_correct/total_sumtrain_acc_list.append(train_acc)# 計算每次循環的損失train_loss = total_loss/total_sumtrain_loss_list.append(train_loss)# 每次循環后打印一次print('train_acc:', train_acc.numpy(), 'train_loss:', train_loss.numpy())

5. 網絡測試

用和訓練過程相同的方法計算損失和準確率,但不需要更新梯度,將每一次迭代的結果保存下來。

    #(6)網絡測試total_sum = 0total_correct = 0total_loss = 0for (x,y) in test_ds:# 前向傳播,得到輸出層結果logits = model(x, training=False)  # 不更新BN層參數# 轉換成每張圖片屬于每個分類的概率prob = tf.nn.softmax(logits, axis=1)# 概率最大的值的索引predict = tf.argmax(prob, axis=1, output_type=tf.int32)# 預測值和真實值比較,相同返回1correct = tf.cast(tf.equal(predict, y), dtype=tf.int32)# 計算相同的個數之和correct_sum = tf.reduce_sum(correct)# 計算準確率total_correct += int(correct_sum)  # 預測對了幾個total_sum += x.shape[0]  # 一共有多少個參與預測# 計算測試集損失y = tf.one_hot(y, depth=10)  # 測試集的目標進行onehot編碼后與預測得到的結果計算交叉熵損失loss = tf.reduce_sum(tf.losses.categorical_crossentropy(y, logits, from_logits=True)) # 每一個batch的總損失total_loss += loss   # 記錄整個循環的損失和# 每個大循環計算一次損失及準確率test_loss = total_loss/total_sum test_acc = total_correct/total_sumprint('test_loss:', test_loss.numpy(),'test_acc:', test_acc)# 保存test_loss_list.append(test_loss)test_acc_list.append(test_acc)

6. 結果展示

網絡迭代10次之后,準確率提高了44%,沒有出現過擬合現象。

---------------------------------------
epochs: 0
step: 0 loss: 3.0574064
step: 100 loss: 1.9813004
step: 200 loss: 1.7280517
step: 300 loss: 1.6263434
train_acc: 0.33082 train_loss: 1.8415068
test_loss: 2.096799 test_acc: 0.2592
---------------
---------------------------------------
.......................................
---------------------------------------
epochs: 9
step: 0 loss: 0.78702605
step: 100 loss: 0.7967223
step: 200 loss: 0.82377315
step: 300 loss: 1.0987799
train_acc: 0.69934 train_loss: 0.8607509
test_loss: 0.8950623 test_acc: 0.6914

7. 模型評估

繪制訓練集和驗證集的準確率和損失的對比曲線,來對網絡優個直觀的感受。可見前10次迭代收斂平緩,效果較好,隨著迭代次數的增加可能會出現過擬合現象。

epochs_range = range(len(train_loss_list))  # 橫坐標,網絡循環了幾次# 準確率曲線
plt.figure(figsize=(10,5))
plt.subplot(1,2,1)
plt.plot(epochs_range, train_acc_list, label='Training_acc')
plt.plot(epochs_range, test_acc_list, label='validation_acc')
plt.legend()
plt.title('Accuracy')
# 損失曲線
plt.subplot(1,2,2)
plt.plot(epochs_range, train_loss_list, label='Training_loss')
plt.plot(epochs_range, test_loss_list, label='validation_loss')
plt.legend()
plt.title('Loss')

總結

以上是生活随笔為你收集整理的【神经网络】(4) 卷积神经网络(CNN),自定义网络,案例:彩色图像10分类的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。