Using Real-world Images
參考:Ubuntu 16 安裝TensorFlow及Jupyter notebook 安裝TensorFlow。
本篇博客翻譯來自 Introduction to TensorFlow for Artificial Intelligence, Machine Learning, and Deep Learning
僅供學習、交流等非盈利性質使用!!!
其他相關文章
Coursera TensorFlow 基礎課程-week4
Coursera TensorFlow 基礎課程-week3
Coursera TensorFlow 基礎課程-week2
Coursera TensorFlow 基礎課程-week1
文章目錄
1. 科技造福人類 & 引入
TensorFlow這項新科技如何造福人類?
從上面的視頻可以看出,一項新技術(比如TensorFlow)確實是可以解決人們面對的實際問題的。
那麼現實生活中的問題,使用TensorFlow怎麼解決呢?
- 現實生活中,圖片肯定不可能全部是28*28像素的(之前處理的圖片都是28*28的);
- 圖片的label也不會整理好給到我們;
- 數據也不會直接分爲訓練集和測試集提供給我們;
所以,就需要了解一些數據的預處理工作,這樣才能真正的把TensorFlow用起來!
2. ImageGenerator介紹
TensorFlow中有一個工具,ImageGenerator,它可以幫我們把數據進行分割,同時進行label化。
如下圖所示:
如果我們建立一個images目錄,然後在其下建立兩個目錄,Training 、Validation,接着,在Training和Validation目錄下面,再分別建立Horse、Human目錄,並把圖片放入其下,那麼使用ImageGenerator就可以自動的把對應目錄的數據分別加載爲訓練集和測試集,並且標籤也會根據目錄的不同,爲每個圖片配上一個對應的標籤。
如果要使用ImageGenerator,那麼需要導入,使用如下代碼:
from tensorflow.keras.preprocessing.image import ImageDataGenerator
加載數據使用下面的代碼:
train_datagen = ImageDataGenerator(rescale= 1./255)
train_generator = train_datagen.flow_from_directory(
train_dir,
target_size =(300,300),
batch_size = 128,
class_model='binary'
)
test_datagen = ImageDataGenerator(rescale= 1./255)
test_generator = test_datagen.flow_from_directory(
test_dir,
target_size =(300,300),
batch_size = 32,
class_model='binary'
)
代碼解釋如下:
- ImageDataGenerator可以指定參數rescale,指定把像素點進行歸一化(如代碼所示,則是把所有像素點都除以255.0);
- train_dir :指的是訓練目錄,如上,則指的是images/Training,test_dir則類似,指的是images/Validation
- target_size指的是把圖像處理後的大小,比如原始圖像是1200*1200,那麼指定這個參數後,其輸出就是300*300 (即圖片的縮放,因爲輸入圖片可能不是一樣的大小,但是TensorFlow的模型卻需要輸入都是一樣的大小,所以這個參數很有用);
- batch_size,則是指一次操作的圖片個數,調整這個值可以獲得不同的執行性能(效率);
- class_mode,這裏特指是二分類,所以使用的是’binary’;
3. 爲識別human 和 horse構建模型
本應用實例是應用TensorFlow來針對提供的圖片構建模型,進而可以識別真實生活中的人和馬。
爲問題定義一個網絡模型,代碼如下:
model = tf.keras.models.Sequential([
tf.keras.layers.Conv2D(16,(3,3),activation='relu',input_shape=(300,300,3)),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Conv2D(32,(3,3),activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
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'),
tf.keras.layers.Dense(1,activation='sigmoid')
])
該代碼解釋如下:
- 最開始定義了3層卷積、池化層;
- 接着定義了一次Flatten、一層Dense,以及最後的Dense;
- 第一層input_shape爲(300,300,3),之前的代碼都是類似(300,300),而沒有後面的3。後面的3指的是顏色3個比特,分別代表,藍色、紅色、黃色。
- 最後的一層Dense只有一個神經元,但是我們是一個二分類,是因爲sigmoid函數,就是使用於二分類的,其效率會比之前的設計效率高(之前使用10個神經元來代表10個類別,當然這裏你也可以使用2個神經元來設計)。
這個模型進行summary,可以得到如下輸出:
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d (Conv2D) (None, 298, 298, 16) 448
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 149, 149, 16) 0
_________________________________________________________________
conv2d_1 (Conv2D) (None, 147, 147, 32) 4640
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 73, 73, 32) 0
_________________________________________________________________
conv2d_2 (Conv2D) (None, 71, 71, 64) 18496
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 35, 35, 64) 0
_________________________________________________________________
flatten (Flatten) (None, 78400) 0
_________________________________________________________________
dense (Dense) (None, 512) 40141312
_________________________________________________________________
dense_1 (Dense) (None, 1) 513
=================================================================
Total params: 40,165,409
Trainable params: 40,165,409
Non-trainable params: 0
_________________________________________________________________
這個輸出,就和前面解釋一樣了,這裏只做個簡單解釋:
- 第一層卷積層filter是3*3,所以輸出像素會少2個(原來是300,現在變爲298);
- 第一層池化層,矩陣是2*2,所以輸出像素少一半(即從298變爲149);
- 其他以此類推;
接着,就可以編譯模型,其代碼如下:
from tensorflow.keras.optimizers import RMSprop
model.compile(loss='binary_crossentropy',
optimizer = RMSprop(lr=0.001),
metrics=['acc']
)
在這個代碼中,損失函數使用二分類的交叉熵函數,優化器使用RMS(此優化器可以調整學習速率-learning rate),打印正確率。
接着就可以訓練模型,如下:
history = model.fit_generator(
train_generator,
steps_per_epoch=8,
epochs=15,
validation_data = validation_generator,
validation_steps = 8,
verbose=2
)
代碼解釋如下:
- 之前代碼用fit來進行建模,現在使用fit_generator,是因爲現在的輸入數據是使用ImageDataGenerator來進行生成的;
- train_generator,就是之前設置的從輸入目錄讀取的變量;
- 一共有1024個圖片,之前設置每次加載128個圖片(batch_size),所以需要加載8次才能加載完全部圖片,所以使用steps_per_epoch=8;
- epochs 設置爲15,那麼訓練15次,當然可以調整;
- validation_data設置爲之前生成的validation_generator;
- 測試數據有256個,之前設置batch_size=32,所以這裏使用validation_steps爲8就可以加載所有圖片了。
- verbose參數設置輸出的信息,設置爲2,則不會輸出建模的過程信息。
4. 識別human和horse實戰
1. 下載並解壓數據
下載數據,在Linux中使用如下命令來下載數據(或在這下載:鏈接:https://pan.baidu.com/s/1NTUQkQyy1P4nkEcUa8wNRA 提取碼:fsfc
):
wget https://storage.googleapis.com/laurencemoroney-blog.appspot.com/horse-or-human.zip
下載後,把其移動到/opt/data/human_horse 目錄,然後使用命令進行解壓,並查看其輸出:
unzip horse-or-human.zip
#ls
horse-or-human.zip horses humans
可以看到有兩個目錄,horses和humans目錄。
2. 數據預覽
- 定義數據目錄:
import os
# horse pictures目錄
train_horse_dir = os.path.join('/opt/data/horse_human/horses')
# human pictures目錄
train_human_dir = os.path.join('/opt/data/horse_human/humans')
- 查看部分數據
train_horse_names = os.listdir(train_horse_dir)
print(train_horse_names[:10])
train_human_names = os.listdir(train_human_dir)
print(train_human_names[:10])
其輸出爲:
['horse33-5.png', 'horse03-9.png', 'horse20-3.png', 'horse44-9.png', 'horse04-7.png', 'horse42-1.png', 'horse06-8.png', 'horse48-8.png', 'horse39-0.png', 'horse07-3.png']
['human12-25.png', 'human15-08.png', 'human02-10.png', 'human13-26.png', 'human02-29.png', 'human14-09.png', 'human14-29.png', 'human11-02.png', 'human09-01.png', 'human16-10.png']
可以看到horse和human的圖片各10個,同時通過文件名也可以知道該圖片的label。
3. 查看數據總個數
print('total training horse images:', len(os.listdir(train_horse_dir)))
print('total training human images:', len(os.listdir(train_human_dir)))
輸出爲:
total training horse images: 500
total training human images: 527
可以看出,馬和人的圖片個數基本是一半一半的。
4. 展示部分圖片
%matplotlib inline
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
# Parameters for our graph; we'll output images in a 4x4 configuration
nrows = 4
ncols = 4
# Index for iterating over images
pic_index = 0
# Set up matplotlib fig, and size it to fit 4x4 pics
fig = plt.gcf()
fig.set_size_inches(ncols * 4, nrows * 4)
pic_index += 8
next_horse_pix = [os.path.join(train_horse_dir, fname)
for fname in train_horse_names[pic_index-8:pic_index]]
next_human_pix = [os.path.join(train_human_dir, fname)
for fname in train_human_names[pic_index-8:pic_index]]
for i, img_path in enumerate(next_horse_pix+next_human_pix):
# Set up subplot; subplot indices start at 1
sp = plt.subplot(nrows, ncols, i + 1)
sp.axis('Off') # Don't show axes (or gridlines)
img = mpimg.imread(img_path)
plt.imshow(img)
plt.show()
執行上述代碼,可以得到如下圖片:
從圖片可以分別看到8個horse和8個human的圖片。
3.構建模型
- 構建模型
model = tf.keras.models.Sequential([
# 輸入直接使用其原始圖片大小 300*300
# This is the first convolution
tf.keras.layers.Conv2D(16, (3,3), activation='relu', input_shape=(300, 300, 3)),
tf.keras.layers.MaxPooling2D(2, 2),
# The second convolution
tf.keras.layers.Conv2D(32, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
# The third convolution
tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
# The fourth convolution
tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
# The fifth convolution
tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
# Flatten the results to feed into a DNN
tf.keras.layers.Flatten(),
# 512 neuron hidden layer
tf.keras.layers.Dense(512, activation='relu'),
# Only 1 output neuron. It will contain a value from 0-1 where 0 for 1 class ('horses') and 1 for the other ('humans')
tf.keras.layers.Dense(1, activation='sigmoid')
])
注意,此處的input_size需要和ImageDataGenerator對應的地方設置其target_size爲對應的值。
2. 編譯模型
from tensorflow.keras.optimizers import RMSprop
model.compile(loss='binary_crossentropy',
optimizer=RMSprop(lr=0.001),
metrics=['acc'])
- 使用ImageDataGenerator構建輸入
from tensorflow.keras.preprocessing.image import ImageDataGenerator
# All images will be rescaled by 1./255
train_datagen = ImageDataGenerator(rescale=1/255)
# Flow training images in batches of 128 using train_datagen generator
train_generator = train_datagen.flow_from_directory(
'/opt/data/horse_human/', # This is the source directory for training images
target_size=(300, 300), # All images will be resized to 300x300
batch_size=128,
# Since we use binary_crossentropy loss, we need binary labels
class_mode='binary')
注意,這裏target_size設置爲300x300,輸出爲:
Found 1027 images belonging to 2 classes.
- 訓練模型
history = model.fit_generator(
train_generator,
steps_per_epoch=8,
epochs=15,
verbose=1)
pip3 install pillow , 如果有相關報錯,需要安裝這個包;
此處設置verbose爲1,則會把建模完整信息進行輸出,如下(虛擬機6G3核可運行,較慢):
Epoch 1/15
9/9 [==============================] - 412s 46s/step - loss: 0.7084 - acc: 0.5696
Epoch 2/15
9/9 [==============================] - 535s 59s/step - loss: 0.7116 - acc: 0.6972
Epoch 3/15
9/9 [==============================] - 385s 43s/step - loss: 0.7930 - acc: 0.7546
Epoch 4/15
9/9 [==============================] - 427s 47s/step - loss: 0.4925 - acc: 0.8169
Epoch 5/15
9/9 [==============================] - 596s 66s/step - loss: 0.2293 - acc: 0.9241
Epoch 6/15
9/9 [==============================] - 366s 41s/step - loss: 0.1235 - acc: 0.9426
Epoch 7/15
9/9 [==============================] - 290s 32s/step - loss: 0.1182 - acc: 0.9513
Epoch 8/15
9/9 [==============================] - 242s 27s/step - loss: 0.2449 - acc: 0.9338
Epoch 9/15
9/9 [==============================] - 273s 30s/step - loss: 0.0659 - acc: 0.9727
Epoch 10/15
9/9 [==============================] - 368s 41s/step - loss: 0.0964 - acc: 0.9649
Epoch 11/15
9/9 [==============================] - 353s 39s/step - loss: 0.0674 - acc: 0.9834
Epoch 12/15
9/9 [==============================] - 428s 48s/step - loss: 0.0714 - acc: 0.9796
Epoch 13/15
9/9 [==============================] - 378s 42s/step - loss: 0.0701 - acc: 0.9776
Epoch 14/15
9/9 [==============================] - 398s 44s/step - loss: 0.1257 - acc: 0.9581
Epoch 15/15
9/9 [==============================] - 373s 41s/step - loss: 0.0505 - acc: 0.9776
可以看到,其輸出正確率可以達到98%左右。
5. 使用真實圖片來進行預測
從網上下載圖片(這四張圖片,也可以從這下載),如下:
從圖片中可以看到有四副真實圖片,包含兩個human和兩個horse,並且其分辨率是不一樣的。
下面使用剛纔咱們構建的模型來進行預測(注意把下載的圖片放到/opt/data/new_human_horse目錄中):
import numpy as np
from tensorflow.keras.preprocessing import image
new_files = os.listdir('/opt/data/new_human_horse')
#print(new_files)
for fn in new_files:
# predicting images
path = '/opt/data/new_human_horse/' + fn
img = image.load_img(path, target_size=(150, 150))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
images = np.vstack([x])
classes = model.predict(images, batch_size=10)
print(classes[0])
if classes[0]>0.5:
print(fn + " is a human")
else:
print(fn + " is a horse")
其輸出爲:
[0.]
human_2d13d9403be7421981a325ff383a0f4a.jpg is a horse
[0.]
human-4320806490398999875.jpg is a horse
[0.]
horse-image-placeholder-title.jpg is a horse
[0.]
horse-th.jpg is a horse
從圖片可以看出,關於human的圖片分類錯誤了。(當然,原視頻中選擇的圖片是都分類正確了,可能和我選的圖片有關???!!!)
- 隨機選擇一個圖片,查看其每層可視化輸出
import numpy as np
import random
from tensorflow.keras.preprocessing.image import img_to_array, load_img
# Let's define a new Model that will take an image as input, and will output
# intermediate representations for all layers in the previous model after
# the first.
successive_outputs = [layer.output for layer in model.layers[1:]]
#visualization_model = Model(img_input, successive_outputs)
visualization_model = tf.keras.models.Model(inputs = model.input, outputs = successive_outputs)
# Let's prepare a random input image from the training set.
horse_img_files = [os.path.join(train_horse_dir, f) for f in train_horse_names]
human_img_files = [os.path.join(train_human_dir, f) for f in train_human_names]
img_path = random.choice(horse_img_files + human_img_files)
img = load_img(img_path, target_size=(300, 300)) # this is a PIL image
x = img_to_array(img) # Numpy array with shape (300, 300, 3)
x = x.reshape((1,) + x.shape) # Numpy array with shape (1, 300, 300, 3)
# Rescale by 1/255
x /= 255
# Let's run our image through our network, thus obtaining all
# intermediate representations for this image.
successive_feature_maps = visualization_model.predict(x)
# These are the names of the layers, so can have them as part of our plot
layer_names = [layer.name for layer in model.layers]
# Now let's display our representations
for layer_name, feature_map in zip(layer_names, successive_feature_maps):
if len(feature_map.shape) == 4:
# Just do this for the conv / maxpool layers, not the fully-connected layers
n_features = feature_map.shape[-1] # number of features in feature map
# The feature map has shape (1, size, size, n_features)
size = feature_map.shape[1]
# We will tile our images in this matrix
display_grid = np.zeros((size, size * n_features))
for i in range(n_features):
# Postprocess the feature to make it visually palatable
x = feature_map[0, :, :, i]
x -= x.mean()
x /= x.std()
x *= 64
x += 128
x = np.clip(x, 0, 255).astype('uint8')
# We'll tile each filter into this big horizontal grid
display_grid[:, i * size : (i + 1) * size] = x
# Display the grid
scale = 20. / n_features
plt.figure(figsize=(scale * n_features, scale))
plt.title(layer_name)
plt.grid(False)
plt.imshow(display_grid, aspect='auto', cmap='viridis')
其輸出爲:
從上往下看,可以認爲是把一個圖片進行轉換,只提取其和目標特徵(此處就是是一個人還是一個馬)相關的特徵。(原文說的是一個蒸餾流程,保留其精華)
- 添加測試:
首先,在這下載測試數據,或使用下面的命令下載測試數據:
wget https://storage.googleapis.com/laurencemoroney-blog.appspot.com/validation-horse-or-human.zip
接着,把其放入目錄/opt/data/horse_human_validation:
# Directory with our training horse pictures
validation_horse_dir = os.path.join('/opt/data/horse_human_validation/horses')
# Directory with our training human pictures
validation_human_dir = os.path.join('/opt/data/horse_human_validation/humans')
接着,構造測試數據的ImageDataGenerator ,如下:
validation_datagen = ImageDataGenerator(rescale=1/255)
# Flow training images in batches of 128 using train_datagen generator
validation_generator = validation_datagen.flow_from_directory(
'/opt/data/horse_human_validation/', # This is the source directory for training images
target_size=(300, 300), # All images will be resized to 150x150
batch_size=32,
# Since we use binary_crossentropy loss, we need binary labels
class_mode='binary')
重新進行model.fit_generator ,指定validation參數,如下:
history = model.fit_generator(
train_generator,
steps_per_epoch=8,
epochs=15,
verbose=1,
validation_data = validation_generator,
validation_steps=8)
其輸出爲:
Epoch 1/15
8/8 [==============================] - 22s 3s/step - loss: 0.7348 - acc: 0.5000
9/9 [==============================] - 362s 40s/step - loss: 0.9071 - acc: 0.5307 - val_loss: 0.7348 - val_acc: 0.5000
Epoch 2/15
8/8 [==============================] - 22s 3s/step - loss: 0.7880 - acc: 0.5078
9/9 [==============================] - 285s 32s/step - loss: 0.8083 - acc: 0.5735 - val_loss: 0.7880 - val_acc: 0.5078
Epoch 3/15
8/8 [==============================] - 40s 5s/step - loss: 0.6607 - acc: 0.5938
9/9 [==============================] - 297s 33s/step - loss: 1.0091 - acc: 0.7322 - val_loss: 0.6607 - val_acc: 0.5938
Epoch 4/15
8/8 [==============================] - 37s 5s/step - loss: 0.4939 - acc: 0.7617
9/9 [==============================] - 283s 31s/step - loss: 0.6453 - acc: 0.6699 - val_loss: 0.4939 - val_acc: 0.7617
Epoch 5/15
8/8 [==============================] - 24s 3s/step - loss: 1.1673 - acc: 0.7695
9/9 [==============================] - 289s 32s/step - loss: 0.3698 - acc: 0.8763 - val_loss: 1.1673 - val_acc: 0.7695
Epoch 6/15
8/8 [==============================] - 23s 3s/step - loss: 0.7771 - acc: 0.7930
9/9 [==============================] - 273s 30s/step - loss: 0.2960 - acc: 0.8627 - val_loss: 0.7771 - val_acc: 0.7930
Epoch 7/15
8/8 [==============================] - 25s 3s/step - loss: 0.5656 - acc: 0.8906
9/9 [==============================] - 284s 32s/step - loss: 0.1102 - acc: 0.9542 - val_loss: 0.5656 - val_acc: 0.8906
Epoch 8/15
8/8 [==============================] - 26s 3s/step - loss: 2.3894 - acc: 0.7031
9/9 [==============================] - 289s 32s/step - loss: 0.3854 - acc: 0.8987 - val_loss: 2.3894 - val_acc: 0.7031
Epoch 9/15
8/8 [==============================] - 36s 5s/step - loss: 2.4947 - acc: 0.7031
9/9 [==============================] - 301s 33s/step - loss: 0.1747 - acc: 0.9445 - val_loss: 2.4947 - val_acc: 0.7031
Epoch 10/15
8/8 [==============================] - 34s 4s/step - loss: 0.2772 - acc: 0.9219
9/9 [==============================] - 471s 52s/step - loss: 0.0700 - acc: 0.9679 - val_loss: 0.2772 - val_acc: 0.9219
Epoch 11/15
8/8 [==============================] - 32s 4s/step - loss: 1.1290 - acc: 0.8008
9/9 [==============================] - 373s 41s/step - loss: 0.8948 - acc: 0.8705 - val_loss: 1.1290 - val_acc: 0.8008
Epoch 12/15
8/8 [==============================] - 43s 5s/step - loss: 1.0806 - acc: 0.8594
9/9 [==============================] - 608s 68s/step - loss: 0.0565 - acc: 0.9834 - val_loss: 1.0806 - val_acc: 0.8594
Epoch 13/15
8/8 [==============================] - 44s 5s/step - loss: 1.1165 - acc: 0.8398
9/9 [==============================] - 552s 61s/step - loss: 0.0357 - acc: 0.9864 - val_loss: 1.1165 - val_acc: 0.8398
Epoch 14/15
8/8 [==============================] - 35s 4s/step - loss: 1.7010 - acc: 0.7617
9/9 [==============================] - 647s 72s/step - loss: 0.0177 - acc: 0.9951 - val_loss: 1.7010 - val_acc: 0.7617
Epoch 15/15
8/8 [==============================] - 35s 4s/step - loss: 1.1240 - acc: 0.8555
9/9 [==============================] - 503s 56s/step - loss: 0.0318 - acc: 0.9854 - val_loss: 1.1240 - val_acc: 0.8555
從上面的結果可以看出,模型對訓練集的效果較好(正確率達到98.5%),對於沒有應用到訓練過程的測試集,效果也還可以(正確率達到85.5%)。
再次對新數據進行分類,結果如下:
[1.]
human_2d13d9403be7421981a325ff383a0f4a.jpg is a human
[0.]
human-4320806490398999875.jpg is a horse
[0.]
horse-image-placeholder-title.jpg is a horse
[0.]
horse-th.jpg is a horse
發現只有一個human被分錯了,說明精度有所提升;
- 壓縮圖片:
上面在測試的時候,使用target_size爲300 ,如果把其改爲150會如何呢?
把相關模塊改爲150後,再次訓練模型,輸出爲:
Epoch 1/15
8/8 [==============================] - 8s 963ms/step - loss: 0.6753 - acc: 0.5000
9/9 [==============================] - 76s 8s/step - loss: 0.7239 - acc: 0.5278 - val_loss: 0.6753 - val_acc: 0.5000
Epoch 2/15
8/8 [==============================] - 9s 1s/step - loss: 0.4213 - acc: 0.8438
9/9 [==============================] - 73s 8s/step - loss: 0.7311 - acc: 0.7050 - val_loss: 0.4213 - val_acc: 0.8438
Epoch 3/15
8/8 [==============================] - 9s 1s/step - loss: 1.0088 - acc: 0.6172
9/9 [==============================] - 68s 8s/step - loss: 0.5170 - acc: 0.8169 - val_loss: 1.0088 - val_acc: 0.6172
Epoch 4/15
8/8 [==============================] - 8s 980ms/step - loss: 0.3365 - acc: 0.8828
9/9 [==============================] - 69s 8s/step - loss: 0.5933 - acc: 0.7897 - val_loss: 0.3365 - val_acc: 0.8828
Epoch 5/15
8/8 [==============================] - 8s 976ms/step - loss: 0.4389 - acc: 0.8516
9/9 [==============================] - 72s 8s/step - loss: 0.2726 - acc: 0.8987 - val_loss: 0.4389 - val_acc: 0.8516
Epoch 6/15
8/8 [==============================] - 8s 943ms/step - loss: 1.1277 - acc: 0.8008
9/9 [==============================] - 71s 8s/step - loss: 0.1266 - acc: 0.9494 - val_loss: 1.1277 - val_acc: 0.8008
Epoch 7/15
8/8 [==============================] - 9s 1s/step - loss: 1.9571 - acc: 0.6953
9/9 [==============================] - 72s 8s/step - loss: 0.1502 - acc: 0.9464 - val_loss: 1.9571 - val_acc: 0.6953
Epoch 8/15
8/8 [==============================] - 11s 1s/step - loss: 0.7124 - acc: 0.8359
9/9 [==============================] - 80s 9s/step - loss: 0.3604 - acc: 0.8763 - val_loss: 0.7124 - val_acc: 0.8359
Epoch 9/15
8/8 [==============================] - 14s 2s/step - loss: 0.6322 - acc: 0.8320
9/9 [==============================] - 85s 9s/step - loss: 0.1740 - acc: 0.9416 - val_loss: 0.6322 - val_acc: 0.8320
Epoch 10/15
8/8 [==============================] - 8s 940ms/step - loss: 0.6428 - acc: 0.8242
9/9 [==============================] - 78s 9s/step - loss: 0.1222 - acc: 0.9640 - val_loss: 0.6428 - val_acc: 0.8242
Epoch 11/15
8/8 [==============================] - 11s 1s/step - loss: 0.8398 - acc: 0.8516
9/9 [==============================] - 72s 8s/step - loss: 0.0538 - acc: 0.9844 - val_loss: 0.8398 - val_acc: 0.8516
Epoch 12/15
8/8 [==============================] - 9s 1s/step - loss: 0.4072 - acc: 0.8242
9/9 [==============================] - 72s 8s/step - loss: 0.5111 - acc: 0.8802 - val_loss: 0.4072 - val_acc: 0.8242
Epoch 13/15
8/8 [==============================] - 8s 996ms/step - loss: 0.8312 - acc: 0.8438
9/9 [==============================] - 72s 8s/step - loss: 0.1396 - acc: 0.9426 - val_loss: 0.8312 - val_acc: 0.8438
Epoch 14/15
8/8 [==============================] - 10s 1s/step - loss: 0.8713 - acc: 0.8477
9/9 [==============================] - 72s 8s/step - loss: 0.1203 - acc: 0.9552 - val_loss: 0.8713 - val_acc: 0.8477
Epoch 15/15
8/8 [==============================] - 8s 1s/step - loss: 1.0197 - acc: 0.8516
9/9 [==============================] - 75s 8s/step - loss: 0.0227 - acc: 0.9942 - val_loss: 1.0197 - val_acc: 0.8516
同時使用新模型來對新數據進行驗證,可以得到結果爲:
[1.]
human_2d13d9403be7421981a325ff383a0f4a.jpg is a human
[0.]
human-4320806490398999875.jpg is a horse
[0.]
horse-image-placeholder-title.jpg is a horse
[0.]
horse-th.jpg is a horse
通過對比,發現:
a. 把target_size改爲150後,訓練過程明顯加快;
b. 改爲150後,模型精度有所下降,對新數據的驗證也有所下降;
5.測試
1.Using Image Generator, how do you label images?
- a. It’s based on the directory the image is contained in
- b. You have to manually do it
- c. It’s based on the file name
- d. TensorFlow figures it out from the contents
What method on the Image Generator is used to normalize the image?
- a. rescale
- b. normalize
- c. Rescale_image
- d. normalize_image
How did we specify the training size for the images?
- a. The training_size parameter on the validation generator
- b. The target_size parameter on the training generator
- c. The target_size parameter on the validation generator
- d. The training_size parameter on the training generator
When we specify the input_shape to be (300, 300, 3), what does that mean?
- a. There will be 300 images, each size 300, loaded in batches of 3
- b. There will be 300 horses and 300 humans, loaded in batches of 3
- c. Every Image will be 300x300 pixels, and there should be 3 Convolutional Layers
- d. Every Image will be 300x300 pixels, with 3 bytes to define color
If your training data is close to 1.000 accuracy, but your validation data isn’t, what’s the risk here?
- a. You’re overfitting on your training data
- b. You’re overfitting on your validation data
- c. No risk, that’s a great result
- d. You’re underfitting on your validation data
Convolutional Neural Networks are better for classifying images like horses and humans because:
- a. In these images, the features may be in different parts of the frame
- b. There’s a wide variety of horses
- c. There’s a wide variety of humans
- d. All of the above
After reducing the size of the images, the training results were different. Why?
- a. There was more condensed information in the images
- b. There was less information in the images
- c. The training was faster
- d. We removed some convolutions to handle the smaller images
My guess:
- a
- a
- b
- d
- a
- d
- b
6.最後的題目
根據提供的數據,包含80個圖片,其中40個笑臉,40個哭臉,需要你訓練一個模型,需要精確率達到99.9%+。
提示:3層卷積層效果最好!
提示代碼如下:
注意,先下載數據 或使用命令下載:
wget https://storage.googleapis.com/laurencemoroney-blog.appspot.com/happy-or-sad.zip
下載完成後,解壓,並移動到/opt/data/happy_sad 目錄
import tensorflow as tf
import os
DESIRED_ACCURACY = 0.999
class myCallback(# Your Code):
# Your Code
callbacks = myCallback()
# This Code Block should Define and Compile the Model
model = tf.keras.models.Sequential([
# Your Code Here
])
from tensorflow.keras.optimizers import RMSprop
model.compile(# Your Code Here #)
# This code block should create an instance of an ImageDataGenerator called train_datagen
# And a train_generator by calling train_datagen.flow_from_directory
from tensorflow.keras.preprocessing.image import ImageDataGenerator
train_datagen = # Your Code Here
train_generator = train_datagen.flow_from_directory(
# Your Code Here)
# Expected output: 'Found 80 images belonging to 2 classes'
# This code block should call model.fit_generator and train for
# a number of epochs.
history = model.fit_generator(
# Your Code Here)
# Expected output: "Reached 99.9% accuracy so cancelling training!""