TensorFlow2基礎:CNN影像分類
1. 導包
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import tensorflow as tf
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
2. 影像分類 fashion_mnist
資料處理
# 原始資料
(X_train_all, y_train_all),(X_test, y_test) = tf.keras.datasets.fashion_mnist.load_data()
# 訓練集、驗證集拆分
X_train, X_valid, y_train, y_valid = train_test_split(X_train_all, y_train_all, test_size=0.25)
# 資料標準化,你也可以用除以255的方式實現歸一化
# 注意最後reshape中的1,代表影像只有一個channel,即當前影像是灰度圖
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train.reshape(-1, 28 * 28)).reshape(-1, 28, 28, 1)
X_valid_scaled = scaler.transform(X_valid.reshape(-1, 28 * 28)).reshape(-1, 28, 28, 1)
X_test_scaled = scaler.transform(X_test.reshape(-1, 28 * 28)).reshape(-1, 28, 28, 1)
構建CNN模型
model = tf.keras.models.Sequential()
# 多個卷積層
model.add(tf.keras.layers.Conv2D(filters=32, kernel_size=[5, 5], padding="same", activation="relu", input_shape=(28, 28, 1)))
model.add(tf.keras.layers.MaxPool2D(pool_size=[2, 2], strides=2))
model.add(tf.keras.layers.Conv2D(filters=64, kernel_size=[5, 5], padding="same", activation="relu"))
model.add(tf.keras.layers.MaxPool2D(pool_size=[2, 2], strides=2))
# 將前面卷積層得出的多維資料轉為一維
# 7和前面的kernel_size、padding、MaxPool2D有關
# Conv2D: 28*28 -> 28*28 (因為padding="same")
# MaxPool2D: 28*28 -> 14*14
# Conv2D: 14*14 -> 14*14 (因為padding="same")
# MaxPool2D: 14*14 -> 7*7
model.add(tf.keras.layers.Reshape(target_shape=(7 * 7 * 64,)))
# 傳入全連線層
model.add(tf.keras.layers.Dense(1024, activation="relu"))
model.add(tf.keras.layers.Dense(10, activation="softmax"))
# compile
model.compile(loss = "sparse_categorical_crossentropy",
optimizer = "sgd",
metrics = ["accuracy"])
模型訓練
callbacks = [
tf.keras.callbacks.EarlyStopping(min_delta=1e-3, patience=5)
]
history = model.fit(X_train_scaled, y_train, epochs=15,
validation_data=(X_valid_scaled, y_valid),
callbacks = callbacks)
Train on 50000 samples, validate on 10000 samples
Epoch 1/15
50000/50000 [==============================] - 17s 343us/sample - loss: 0.5707 - accuracy: 0.7965 - val_loss: 0.4631 - val_accuracy: 0.8323
Epoch 2/15
50000/50000 [==============================] - 13s 259us/sample - loss: 0.3728 - accuracy: 0.8669 - val_loss: 0.3573 - val_accuracy: 0.8738
...
Epoch 13/15
50000/50000 [==============================] - 12s 244us/sample - loss: 0.1625 - accuracy: 0.9407 - val_loss: 0.2489 - val_accuracy: 0.9112
Epoch 14/15
50000/50000 [==============================] - 12s 240us/sample - loss: 0.1522 - accuracy: 0.9451 - val_loss: 0.2584 - val_accuracy: 0.9104
Epoch 15/15
50000/50000 [==============================] - 12s 237us/sample - loss: 0.1424 - accuracy: 0.9500 - val_loss: 0.2521 - val_accuracy: 0.9114
作圖
def plot_learning_curves(history):
pd.DataFrame(history.history).plot(figsize=(8, 5))
plt.grid(True)
#plt.gca().set_ylim(0, 1)
plt.show()
plot_learning_curves(history)
測試集評估準確率
model.evaluate(X_test_scaled, y_test)
[0.269884311157465, 0.9071]
可以看到使用CNN後,影像分類的準確率明顯提升了。之前的模型是0.8747,現在是0.9071。
3. 影像分類 Dogs vs. Cats
3.1 原始資料
原始資料下載
Kaggle:
百度網盤: 提取碼 dmp4
讀取一張圖片,並展示
image_string = tf.io.read_file("C:/Users/Skey/Downloads/datasets/cat_vs_dog/train/cat.28.jpg")
image_decoded = tf.image.decode_jpeg(image_string)
plt.imshow(image_decoded)
3.2 利用Dataset載入圖片
由於原始圖片過多,我們不能將所有圖片一次載入入記憶體。Tensorflow為我們提供了便利的Dataset API,可以從硬碟中一批一批的載入資料,以用於訓練。
處理本地圖片路徑與標籤
# 訓練資料的路徑
train_dir = "C:/Users/Skey/Downloads/datasets/cat_vs_dog/train/"
train_filenames = [] # 所有圖片的檔名
train_labels = [] # 所有圖片的標籤
for filename in os.listdir(train_dir):
train_filenames.append(train_dir + filename)
if (filename.startswith("cat")):
train_labels.append(0) # 將cat標記為0
else:
train_labels.append(1) # 將dog標記為1
# 資料隨機拆分 鄭州人流哪家醫院做的好
X_train, X_valid, y_train, y_valid = train_test_split(train_filenames, train_labels, test_size=0.2)
定義一個解碼圖片的方法
def _decode_and_resize(filename, label):
image_string = tf.io.read_file(filename) # 讀取圖片
image_decoded = tf.image.decode_jpeg(image_string) # 解碼
image_resized = tf.image.resize(image_decoded, [256, 256]) / 255.0 # 重置size,並歸一化
return image_resized, label
定義 Dataset,用於載入圖片資料
# 訓練集
train_dataset = tf.data.Dataset.from_tensor_slices((train_filenames, train_labels))
train_dataset = train_dataset.map(
map_func=_decode_and_resize, # 呼叫前面定義的方法,解析filename,轉為特徵和標籤
num_parallel_calls=tf.data.experimental.AUTOTUNE)
train_dataset = train_dataset.shuffle(buffer_size=128) # 設定緩衝區大小
train_dataset = train_dataset.batch(32) # 每批資料的量
train_dataset = train_dataset.prefetch(tf.data.experimental.AUTOTUNE) # 啟動預載入圖片,也就是說CPU會提前從磁碟載入資料,不用等上一次訓練完後再載入
# 驗證集
valid_dataset = tf.data.Dataset.from_tensor_slices((valid_filenames, valid_labels))
valid_dataset = valid_dataset.map(
map_func=_decode_and_resize,
num_parallel_calls=tf.data.experimental.AUTOTUNE)
valid_dataset = valid_dataset.batch(32)
3.3 構建CNN模型,並訓練
構建模型與編譯
model = tf.keras.Sequential([
# 卷積,32個filter(卷積核),每個大小為3*3,步長為1
tf.keras.layers.Conv2D(32, 3, activation='relu', input_shape=(256, 256, 3)),
# 池化,預設大小2*2,步長為2
tf.keras.layers.MaxPooling2D(),
tf.keras.layers.Conv2D(32, 5, activation='relu'),
tf.keras.layers.MaxPooling2D(),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(64, activation='relu'),
tf.keras.layers.Dense(2, activation='softmax')
])
model.compile(
optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),
loss=tf.keras.losses.sparse_categorical_crossentropy,
metrics=[tf.keras.metrics.sparse_categorical_accuracy]
)
模型總覽
model.summary()
Model: "sequential_1"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_2 (Conv2D) (None, 254, 254, 32) 896
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 127, 127, 32) 0
_________________________________________________________________
conv2d_3 (Conv2D) (None, 123, 123, 32) 25632
_________________________________________________________________
max_pooling2d_3 (MaxPooling2 (None, 61, 61, 32) 0
_________________________________________________________________
flatten_1 (Flatten) (None, 119072) 0
_________________________________________________________________
dense_2 (Dense) (None, 64) 7620672
_________________________________________________________________
dense_3 (Dense) (None, 2) 130
=================================================================
Total params: 7,647,330
Trainable params: 7,647,330
Non-trainable params: 0
開始訓練
model.fit(train_dataset, epochs=10, validation_data=valid_dataset)
由於資料量大,此處訓練時間較久
需要注意的是此處列印的step,每個step指的是一個batch(例如32個樣本一個batch)
模型評估
test_dataset = tf.data.Dataset.from_tensor_slices((valid_filenames, valid_labels))
test_dataset = test_dataset.map(_decode_and_resize)
test_dataset = test_dataset.batch(32)
print(model.metrics_names)
print(model.evaluate(test_dataset))
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69945560/viewspace-2680033/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 基於Tensorflow + Opencv 實現CNN自定義影像分類OpenCVCNN
- 1.CNN圖片單標籤分類(基於TensorFlow實現基礎VGG16網路)CNN
- 基於PaddlePaddle的影像分類實戰 | 深度學習基礎任務教程系列(一)深度學習
- 二分類問題 - 【老魚學tensorflow2】
- 「影像分類」 實戰影像分類網路的視覺化視覺化
- CNN-簡單圖片分類CNN
- 二分類問題續 - 【老魚學tensorflow2】
- NLP-使用CNN進行文字分類CNN文字分類
- 演算法影像崗-影像分類與影像分割演算法
- ArcGIS中的影像分類
- AI從入門到放棄:CNN的導火索,用MLP做影像分類識別?AICNN
- (一)文字分類經典模型之CNN篇文字分類模型CNN
- CNN+pytorch實現文字二分類CNNPyTorch
- Tensorflow 1.x 影像分類
- 最基礎的分類演算法(KNN)演算法KNN
- 【機器學習基礎】卷積神經網路(CNN)基礎機器學習卷積神經網路CNN
- 【scipy 基礎】--影像處理
- 零基礎搭建智慧垃圾分類小程式
- 棉花病害影像分類資料集
- 水稻病害影像分類資料集
- 文字分類(下)-卷積神經網路(CNN)在文字分類上的應用文字分類卷積神經網路CNN
- 基於支援向量機的影像分類系統(MATLAB GUI介面版)MatlabGUI
- 基於影像視覺詞彙的文字分類方法(完整專案)視覺文字分類
- 亞馬遜:用CNN進行影象分類的Tricks亞馬遜CNN
- Tensorflow2 自定義資料集圖片完成圖片分類任務
- 影像處理基礎篇(一)
- 【傳統影像處理】1 數字影像基礎
- CVPR 2019 | 弱監督影像分類建模
- 【TensorFlow】 TensorFlow-Slim影像分類模型庫模型
- Oracle分割槽表基礎運維-01分割槽表分類Oracle運維
- CNN--卷積神經網路從R-CNN到Faster R-CNN的理解(CIFAR10分類程式碼)CNN卷積神經網路AST
- 【scikit-learn基礎】--『預處理』之 分類編碼
- 人工智慧的預訓練基礎模型的分類人工智慧模型
- 『忘了再學』Shell基礎 — 2、Shell的作用與分類
- mysql基礎複習(SQL語句的四個分類),MySql
- 2.CNN圖片多標籤分類(基於TensorFlow實現驗證碼識別OCR)CNN
- 影像識別垃圾分類app的製作APP
- 視覺化影像處理 | 視覺化訓練器 | 影像分類視覺化