CIFAR是另外一種數據集,包含了如下10中數據。
本次實驗採用VGG網絡模型,精度非常高,resnet殘差網絡模型沒有測試成功,在擬合時候一直不收斂
加載數據集
(x,y), (x_test, y_test) = datasets.cifar10.load_data()
剔除標籤多餘維度
y = tf.squeeze(y, axis=1) #tf.Tensor([6 9 9 ... 9 1 1]
y_test = tf.squeeze(y_test, axis=1)
構建Dataset數據集,打散,數據歸一化,類型轉換,batch處理
train_db = tf.data.Dataset.from_tensor_slices((x,y))
train_db = train_db.shuffle(1000).map(preprocess).batch(128)
test_db = tf.data.Dataset.from_tensor_slices((x_test,y_test))
test_db = test_db.map(preprocess).batch(64)
def preprocess(x, y):
# [0~1]
x = 2*tf.cast(x, dtype=tf.float32) / 255.-1
y = tf.cast(y, dtype=tf.int32)
return x,y
卷積層模型
conv_layers = [ # 5 units of conv + max pooling
# unit 1
layers.Conv2D(64, kernel_size=[3, 3], padding="same", activation=tf.nn.relu),
layers.Conv2D(64, kernel_size=[3, 3], padding="same", activation=tf.nn.relu),
layers.MaxPool2D(pool_size=[2, 2], strides=2, padding='same'),
# unit 2
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'),
# unit 3
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'),
# unit 4
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'),
# unit 5
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')
]
全鏈接層模型
conv_net = Sequential(conv_layers)
conv_net.add(layers.Flatten())
conv_net.add(tf.keras.layers.Dense(256, activation=tf.nn.relu)) #隱藏層
conv_net.add(tf.keras.layers.Dense(128, activation=tf.nn.relu))
conv_net.add(tf.keras.layers.Dense(10, activation='softmax')) #輸出層 tf.nn.softmax
編譯
conv_net.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
擬合
conv_net.fit(train_db, epochs=100)
估值
val_loss, val_acc = conv_net.evaluate(test_db) # 測試集,損失值,準確度返回
print(val_loss)
print(val_acc)
模型保存
conv_net.save('model_vgg_cifar.h5')
預測圖片如下:
加載模型
model = tf.keras.models.load_model('model_vgg_cifar.h5')
處理圖片爲32*32
(filepath,filename) = os.path.split(path)
img = cv2.imread(path)
img = cv2.resize(img, (32, 32))
path = filepath+'/32_32/'+filename
cv2.imwrite(path,img)
print(path)
轉換維度和類型
img = np.reshape(img,(1,32,32,3))
img = img.astype(float32)
歸一化到-1~1
img = 2 * tf.cast(img, dtype=tf.float32) / 255. - 1
預測
predictions = model.predict(img)
print(predictions)
index = np.argmax(predictions[0])
print(index,NumToEcode(index))
def NumToEcode(num):
list = ["airplan","car","bird","cat","deer","dog","frog","horse","ship","truck"]
return list[num]
實驗結果如下:
完整代碼如下:
import tensorflow as tf
from tensorflow.keras import layers, optimizers, datasets, Sequential
import os
import sys
import cv2
import numpy as np
import matplotlib.pyplot as plt
from numpy import float32,float64
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'
tf.random.set_seed(2345)
conv_layers = [ # 5 units of conv + max pooling
# unit 1
layers.Conv2D(64, kernel_size=[3, 3], padding="same", activation=tf.nn.relu),
layers.Conv2D(64, kernel_size=[3, 3], padding="same", activation=tf.nn.relu),
layers.MaxPool2D(pool_size=[2, 2], strides=2, padding='same'),
# unit 2
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'),
# unit 3
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'),
# unit 4
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'),
# unit 5
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')
]
def preprocess(x, y):
# [0~1]
x = 2*tf.cast(x, dtype=tf.float32) / 255.-1
y = tf.cast(y, dtype=tf.int32)
return x,y
def show(img):
cv2.imshow("pWinName", img)
cv2.waitKey(0)
#裝載圖像矩陣數據
(x,y), (x_test, y_test) = datasets.cifar10.load_data() #(50000, 32, 32, 3) (50000, 1) (10000, 32, 32, 3) (10000, 1)
y = tf.squeeze(y, axis=1) #tf.Tensor([6 9 9 ... 9 1 1]
y_test = tf.squeeze(y_test, axis=1)
print(x.shape, y.shape, x_test.shape, y_test.shape)
train_db = tf.data.Dataset.from_tensor_slices((x,y))
train_db = train_db.shuffle(1000).map(preprocess).batch(128)
test_db = tf.data.Dataset.from_tensor_slices((x_test,y_test))
test_db = test_db.map(preprocess).batch(64)
sample = next(iter(train_db))
print('sample:', sample[0].shape, sample[1].shape,tf.reduce_min(sample[0]), tf.reduce_max(sample[0]))
def training():
# [b, 32, 32, 3] => [b, 1, 1, 512]
conv_net = Sequential(conv_layers)
conv_net.add(layers.Flatten())
conv_net.add(tf.keras.layers.Dense(256, activation=tf.nn.relu)) #隱藏層
conv_net.add(tf.keras.layers.Dense(128, activation=tf.nn.relu))
conv_net.add(tf.keras.layers.Dense(10, activation='softmax')) #輸出層 tf.nn.softmax
conv_net.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
#conv_net.build(input_shape=(128, 32, 32, 3))
#conv_net.summary()
conv_net.fit(train_db, epochs=100)
val_loss, val_acc = conv_net.evaluate(test_db) # 測試集,損失值,準確度返回
print(val_loss)
print(val_acc)
conv_net.save('model_vgg_cifar.h5')
def NumToEcode(num):
list = ["airplan","car","bird","cat","deer","dog","frog","horse","ship","truck"]
return list[num]
def predicted(path):
model = tf.keras.models.load_model('model_vgg_cifar.h5')
(filepath,filename) = os.path.split(path)
img = cv2.imread(path)
img = cv2.resize(img, (32, 32))
path = filepath+'/32_32/'+filename
cv2.imwrite(path,img)
print(path)
img = np.reshape(img,(1,32,32,3))
img = img.astype(float32)
img = 2 * tf.cast(img, dtype=tf.float32) / 255. - 1
predictions = model.predict(img)
print(predictions)
index = np.argmax(predictions[0])
print(index,NumToEcode(index))
if __name__ == '__main__':
#training()
predicted("./bmp_cifar/airplan.jpg")