天天看點

TensorFlow(9)人馬圖像分類(卷積神經網絡)基礎理論一、準備資料二、建構神經網絡三、編譯、訓練四、預測(單圖預測)總代碼

目錄

基礎理論

1、sigmoid激活函數

2、聚類&&分類

一、準備資料

1、建立兩個資料生成器

2、建立訓練資料與測試資料生成器

 訓練資料生成器

測試資料生成器        

二、建構神經網絡

三、編譯、訓練

四、預測(單圖預測)

1、待預測圖像處理

1-1、讀取圖像

1-2、BGR轉RGB

1-3、顯示圖像

2、圖像資料轉換  

3、預測

總代碼

基礎理論

1、sigmoid激活函數

由于是二分類,是以最後會用到sigmoid激活函數(0、1兩值)。

TensorFlow(9)人馬圖像分類(卷積神經網絡)基礎理論一、準備資料二、建構神經網絡三、編譯、訓練四、預測(單圖預測)總代碼

2、聚類&&分類

        聚類(Clustering):是指把相似的資料劃分到一起,具體劃分的時候并不關心這一類的标簽,目标就是把相似的資料聚合到一起,聚類是一種無監督學習(Unsupervised Learning)方法。

(聚類:不按标簽把相似資料聚合到一起)

        分類(Classification):是把不同的資料劃分開,其過程是通過訓練資料集獲得一個分類器,再通過分類器去預測未知資料,分類是一種監督學習(Supervised Learning)方法。

一、準備資料

資料下載下傳位址:

https://storage.googleapis.com/laurencemoroney-blog.appspot.com/horse-or-human.zip \

    -O /tmp/horse-or-human.zip 

# 1、準備資料
from tensorflow.keras.preprocessing.image import ImageDataGenerator
           

1、建立兩個資料生成器

# 1-1、建立兩個資料生成器
train_data_gen = ImageDataGenerator(rescale=1/255)
test_data_gen = ImageDataGenerator(rescale=1/255)
           

2、建立訓練資料與測試資料生成器

 訓練資料生成器

# 訓練資料生成器(指向訓練資料檔案夾)
train_generator = train_data_gen.flow_from_directory(
    'D:\\Study\\AI\\OpenCV\\horse-human-data\\horse-or-human',
    target_size = (150,150), batch_size = 32, class_mode = 'binary'
#   目标大小                  一批的數量         二分類
)
           

測試資料生成器        

# 測試資料生成器(指向測試資料檔案夾)
test_generator = test_data_gen.flow_from_directory(
    'D:\\Study\\AI\\OpenCV\\horse-human-data\\validation-horse-or-human',
    target_size = (150,150), batch_size = 32, class_mode = 'binary'
)
           
TensorFlow(9)人馬圖像分類(卷積神經網絡)基礎理論一、準備資料二、建構神經網絡三、編譯、訓練四、預測(單圖預測)總代碼

二、建構神經網絡

# 2、建構神經網絡
import tensorflow as tf
from tensorflow.keras.optimizers import RMSprop

# 神經網絡模型
model = tf.keras.models.Sequential([
    # 第一層CNN
    tf.keras.layers.Conv2D(16, (3,3), activation='relu', input_shape=(150, 150, 3)),
    tf.keras.layers.MaxPooling2D(2, 2),
    # 第二層CNN
    tf.keras.layers.Conv2D(32, (3,3), activation='relu'),
    tf.keras.layers.MaxPooling2D(2,2),
    # 第三層CNN
    tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
    tf.keras.layers.MaxPooling2D(2,2),
    # 第四層CNN
    tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
    tf.keras.layers.MaxPooling2D(2,2),
    # 第五層CNN
    tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
    tf.keras.layers.MaxPooling2D(2,2),
    
    # 輸入層
    tf.keras.layers.Flatten(),
    # 隐層
    tf.keras.layers.Dense(512, activation='relu'),
    # 輸出層:用sigmoid激活函數二分類(隻有一個神經元,結果隻有0和1,分别對應人和馬)
    tf.keras.layers.Dense(1, activation='sigmoid')
])
# 可視化
model.summary()
           

Model: "sequential_3" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= conv2d_15 (Conv2D) (None, 148, 148, 16) 448 _________________________________________________________________ max_pooling2d_15 (MaxPooling (None, 74, 74, 16) 0 _________________________________________________________________ conv2d_16 (Conv2D) (None, 72, 72, 32) 4640 _________________________________________________________________ max_pooling2d_16 (MaxPooling (None, 36, 36, 32) 0 _________________________________________________________________ conv2d_17 (Conv2D) (None, 34, 34, 64) 18496 _________________________________________________________________ max_pooling2d_17 (MaxPooling (None, 17, 17, 64) 0 _________________________________________________________________ conv2d_18 (Conv2D) (None, 15, 15, 64) 36928 _________________________________________________________________ max_pooling2d_18 (MaxPooling (None, 7, 7, 64) 0 _________________________________________________________________ conv2d_19 (Conv2D) (None, 5, 5, 64) 36928 _________________________________________________________________ max_pooling2d_19 (MaxPooling (None, 2, 2, 64) 0 _________________________________________________________________ flatten_3 (Flatten) (None, 256) 0 _________________________________________________________________ dense_6 (Dense) (None, 512) 131584 _________________________________________________________________ dense_7 (Dense) (None, 1) 513 ================================================================= Total params: 229,537 Trainable params: 229,537 Non-trainable params: 0 _________________________________________________________________

三、編譯、訓練

# 3、編譯&&訓練
model.compile(loss='binary_crossentropy', optimizer=RMSprop(lr=0.001), metrics=['acc'])
model.fit(train_generator, epochs=5, validation_data=test_generator)
#         訓練集            疊代次數   測試集
           
Epoch 1/10
33/33 [==============================] - 18s 544ms/step - loss: 0.5144 - acc: 0.7420 - val_loss: 0.6703 - val_acc: 0.8438
Epoch 2/10
33/33 [==============================] - 18s 548ms/step - loss: 0.1962 - acc: 0.9299 - val_loss: 0.7632 - val_acc: 0.8594
Epoch 3/10
33/33 [==============================] - 18s 558ms/step - loss: 0.1640 - acc: 0.9445 - val_loss: 0.7594 - val_acc: 0.8594
Epoch 4/10
33/33 [==============================] - 18s 551ms/step - loss: 0.0940 - acc: 0.9640 - val_loss: 1.0639 - val_acc: 0.8398
Epoch 5/10
33/33 [==============================] - 18s 544ms/step - loss: 0.0851 - acc: 0.9747 - val_loss: 1.4272 - val_acc: 0.8633
Epoch 6/10
33/33 [==============================] - 18s 551ms/step - loss: 0.0774 - acc: 0.9698 - val_loss: 1.0516 - val_acc: 0.8516
Epoch 7/10
33/33 [==============================] - 19s 562ms/step - loss: 0.0113 - acc: 0.9981 - val_loss: 2.2403 - val_acc: 0.7734
Epoch 8/10
33/33 [==============================] - 18s 549ms/step - loss: 0.0689 - acc: 0.9786 - val_loss: 1.3702 - val_acc: 0.8672
Epoch 9/10
33/33 [==============================] - 18s 549ms/step - loss: 0.0043 - acc: 1.0000 - val_loss: 2.0496 - val_acc: 0.8594
Epoch 10/10
33/33 [==============================] - 18s 556ms/step - loss: 0.0572 - acc: 0.9873 - val_loss: 1.8541 - val_acc: 0.8633
      

[12]:

<tensorflow.python.keras.callbacks.History at 0x7fa1b05ddcd0>      

四、預測(單圖預測)

1、待預測圖像處理

1-1、讀取圖像

import cv2
import matplotlib.pyplot as plt
import numpy as np

# (1) 讀取圖像
# img1:馬    img2:人
img1 = cv2.imread('tensorflow_datasets/validation-horse-or-human/horses/horse1-000.png')
img1 = cv2.resize(img1, (150, 150))
img2 = cv2.imread('tensorflow_datasets/validation-horse-or-human/humans/valhuman01-01.png')
img2 = cv2.resize(img2, (150, 150))
           

1-2、BGR轉RGB

BGR轉RGB(opencv的色彩空間是BGR,plt色彩空間是RGB)。
      
# (2) BGR轉RGB
# OpenCV中圖檔像素按照BGR方式排列;而Matpoltlib中圖檔按照RGB方式排序
b,g,r = cv2.split(img1)    #分離
img1 = cv2.merge([r,g,b])  #合并
b,g,r = cv2.split(img2)    #分離
img2 = cv2.merge([r,g,b])  #合并
           

1-3、顯示圖像

# (3) 顯示圖像
f, ax = plt.subplots(1, 2)
ax[0].imshow(img1)
ax[0].set_title("0")
ax[1].imshow(img2)
ax[1].set_title("1")
plt.show()
           
TensorFlow(9)人馬圖像分類(卷積神經網絡)基礎理論一、準備資料二、建構神經網絡三、編譯、訓練四、預測(單圖預測)總代碼

如果不進行BGR轉RGB的操作,就會出現這樣色彩錯亂的情況:

TensorFlow(9)人馬圖像分類(卷積神經網絡)基礎理論一、準備資料二、建構神經網絡三、編譯、訓練四、預測(單圖預測)總代碼

 (來自冥界的人馬

TensorFlow(9)人馬圖像分類(卷積神經網絡)基礎理論一、準備資料二、建構神經網絡三、編譯、訓練四、預測(單圖預測)總代碼

2、圖像資料轉換  

這裡model.predict()的預測需要更高次元的圖像資料,進行一下轉換。

# 圖像轉資料(用來做預測)
Img1 = np.expand_dims(img1, axis=0)    #轉三維資料(二維轉三維)
Img2 = np.expand_dims(img2, axis=0)    #轉三維資料(二維轉三維)
           

img:

TensorFlow(9)人馬圖像分類(卷積神經網絡)基礎理論一、準備資料二、建構神經網絡三、編譯、訓練四、預測(單圖預測)總代碼

Img:

TensorFlow(9)人馬圖像分類(卷積神經網絡)基礎理論一、準備資料二、建構神經網絡三、編譯、訓練四、預測(單圖預測)總代碼

3、預測

# 4、預測(分别對兩個圖進行預測)
for i in range(2):
    if i==0:
        # 對圖像1做預測
        classes = model.predict(Img1, batch_size=10)
        print(f'{i}号圖檔預測結果為:', int(classes[0][0]), '馬')
    elif i==1:
        # 對圖像2做預測
        classes = model.predict(Img2, batch_size=10)
        print(f'{i}号圖檔預測結果為:', int(classes[0][0]), '人')
           
TensorFlow(9)人馬圖像分類(卷積神經網絡)基礎理論一、準備資料二、建構神經網絡三、編譯、訓練四、預測(單圖預測)總代碼

總代碼

# 1、準備資料
from tensorflow.keras.preprocessing.image import ImageDataGenerator

# 1-1、建立兩個資料生成器
train_data_gen = ImageDataGenerator(rescale=1/255)
test_data_gen = ImageDataGenerator(rescale=1/255)

# 1-2、建立訓練資料與測試資料生成器
# 訓練資料生成器(指向訓練資料檔案夾)
train_generator = train_data_gen.flow_from_directory(
    'tensorflow_datasets/horse-or-human/',
    target_size = (150,150), batch_size = 32, class_mode = 'binary'
#   目标大小                  一批的數量         二分類
)

# 測試資料生成器(指向測試資料檔案夾)
test_generator = test_data_gen.flow_from_directory(
    'tensorflow_datasets/validation-horse-or-human/',
    target_size = (150,150), batch_size = 32, class_mode = 'binary'
)


# 2、建構神經網絡
import tensorflow as tf
from tensorflow.keras.optimizers import RMSprop

# 神經網絡模型
model = tf.keras.models.Sequential([
    # 第一層CNN
    tf.keras.layers.Conv2D(16, (3, 3), activation='relu', input_shape=(150, 150, 3)),
    tf.keras.layers.MaxPooling2D(2, 2),
    # 第二層CNN
    tf.keras.layers.Conv2D(32, (3, 3), activation='relu'),
    tf.keras.layers.MaxPooling2D(2, 2),
    # 第三層CNN
    tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),
    tf.keras.layers.MaxPooling2D(2, 2),
    # 第四層CNN
    tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),
    tf.keras.layers.MaxPooling2D(2, 2),
    # 第五層CNN
    tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),
    tf.keras.layers.MaxPooling2D(2, 2),

    # 輸入層
    tf.keras.layers.Flatten(),
    # 隐層
    tf.keras.layers.Dense(512, activation='relu'),
    # 輸出層:用sigmoid激活函數二分類(隻有一個神經元,結果隻有0和1,分别對應人和馬)
    tf.keras.layers.Dense(1, activation='sigmoid')
])
# 可視化
model.summary()


# 3、編譯&&訓練
model.compile(loss='binary_crossentropy', optimizer=RMSprop(lr=0.001), metrics=['acc'])
model.fit(train_generator, epochs=10, validation_data=test_generator)
#         訓練集            疊代次數   測試集


# 4、預測
import cv2
import matplotlib.pyplot as plt
import numpy as np

# (1) 讀取圖像
# img1:馬    img2:人
img1 = cv2.imread('tensorflow_datasets/validation-horse-or-human/horses/horse1-000.png')
img1 = cv2.resize(img1, (150, 150))
img2 = cv2.imread('tensorflow_datasets/validation-horse-or-human/humans/valhuman01-01.png')
img2 = cv2.resize(img2, (150, 150))

# (2) BGR轉RGB
# OpenCV中圖檔像素按照BGR方式排列;而Matpoltlib中圖檔按照RGB方式排序
b,g,r = cv2.split(img1)    #分離
img1 = cv2.merge([r,g,b])  #合并
b,g,r = cv2.split(img2)    #分離
img2 = cv2.merge([r,g,b])  #合并

# (3) 顯示圖像
f, ax = plt.subplots(1, 2)
ax[0].imshow(img1)
ax[1].imshow(img2)
plt.show()

# 圖像轉資料(用來做預測)
Img1 = np.expand_dims(img1, axis=0)    #轉三維資料(二維轉三維)
Img2 = np.expand_dims(img2, axis=0)    #轉三維資料(二維轉三維)


# 4、預測(分别對兩個圖進行預測)
for i in range(2):
    if i==0:
        # 對圖像1做預測
        classes = model.predict(Img1, batch_size=10)
        print(f'{i}号圖檔預測結果為:', int(classes[0][0]), '馬')
    elif i==1:
        # 對圖像2做預測
        classes = model.predict(Img2, batch_size=10)
        print(f'{i}号圖檔預測結果為:', int(classes[0][0]), '人')
           

繼續閱讀