Coursera TensorFlow 基礎課程-week4

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這項新科技如何造福人類?

請看: here
從這下載

從上面的視頻可以看出,一項新技術(比如TensorFlow)確實是可以解決人們面對的實際問題的。

那麼現實生活中的問題,使用TensorFlow怎麼解決呢?

  1. 現實生活中,圖片肯定不可能全部是28*28像素的(之前處理的圖片都是28*28的);
  2. 圖片的label也不會整理好給到我們;
  3. 數據也不會直接分爲訓練集和測試集提供給我們;

所以,就需要了解一些數據的預處理工作,這樣才能真正的把TensorFlow用起來!

2. ImageGenerator介紹

TensorFlow中有一個工具,ImageGenerator,它可以幫我們把數據進行分割,同時進行label化。

如下圖所示:

image

如果我們建立一個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'
)

代碼解釋如下:

  1. ImageDataGenerator可以指定參數rescale,指定把像素點進行歸一化(如代碼所示,則是把所有像素點都除以255.0);
  2. train_dir :指的是訓練目錄,如上,則指的是images/Training,test_dir則類似,指的是images/Validation
  3. target_size指的是把圖像處理後的大小,比如原始圖像是1200*1200,那麼指定這個參數後,其輸出就是300*300 (即圖片的縮放,因爲輸入圖片可能不是一樣的大小,但是TensorFlow的模型卻需要輸入都是一樣的大小,所以這個參數很有用);
  4. batch_size,則是指一次操作的圖片個數,調整這個值可以獲得不同的執行性能(效率);
  5. 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')
])

該代碼解釋如下:

  1. 最開始定義了3層卷積、池化層;
  2. 接着定義了一次Flatten、一層Dense,以及最後的Dense;
  3. 第一層input_shape爲(300,300,3),之前的代碼都是類似(300,300),而沒有後面的3。後面的3指的是顏色3個比特,分別代表,藍色、紅色、黃色。
  4. 最後的一層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
_________________________________________________________________

這個輸出,就和前面解釋一樣了,這裏只做個簡單解釋:

  1. 第一層卷積層filter是3*3,所以輸出像素會少2個(原來是300,現在變爲298);
  2. 第一層池化層,矩陣是2*2,所以輸出像素少一半(即從298變爲149);
  3. 其他以此類推;

接着,就可以編譯模型,其代碼如下:

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
)

代碼解釋如下:

  1. 之前代碼用fit來進行建模,現在使用fit_generator,是因爲現在的輸入數據是使用ImageDataGenerator來進行生成的;
  2. train_generator,就是之前設置的從輸入目錄讀取的變量;
  3. 一共有1024個圖片,之前設置每次加載128個圖片(batch_size),所以需要加載8次才能加載完全部圖片,所以使用steps_per_epoch=8;
  4. epochs 設置爲15,那麼訓練15次,當然可以調整;
  5. validation_data設置爲之前生成的validation_generator;
  6. 測試數據有256個,之前設置batch_size=32,所以這裏使用validation_steps爲8就可以加載所有圖片了。
  7. 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. 數據預覽

  1. 定義數據目錄:
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')
  1. 查看部分數據
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()

執行上述代碼,可以得到如下圖片:

image

從圖片可以分別看到8個horse和8個human的圖片。

3.構建模型

  1. 構建模型
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'])
  1. 使用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.
  1. 訓練模型
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. 使用真實圖片來進行預測
從網上下載圖片(這四張圖片,也可以從這下載),如下:

image

從圖片中可以看到有四副真實圖片,包含兩個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的圖片分類錯誤了。(當然,原視頻中選擇的圖片是都分類正確了,可能和我選的圖片有關???!!!)

  1. 隨機選擇一個圖片,查看其每層可視化輸出
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')

其輸出爲:

image

從上往下看,可以認爲是把一個圖片進行轉換,只提取其和目標特徵(此處就是是一個人還是一個馬)相關的特徵。(原文說的是一個蒸餾流程,保留其精華)

  1. 添加測試:
    首先,在下載測試數據,或使用下面的命令下載測試數據:
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被分錯了,說明精度有所提升;

  1. 壓縮圖片:
    上面在測試的時候,使用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:

  1. a
  2. a
  3. b
  4. d
  5. a
  6. d
  7. 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!""

Answer Download Here
Code Download Here:
First

Second

Third

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章