¸üÐÂʱ¼ä:2023Äê06ÔÂ06ÈÕ15ʱ45·Ö À´Ô´:ÀÖÓãµç¾º ä¯ÀÀ´ÎÊý:
ÈçºÎÔÚÖ»ÓÐ6ÍòÕÅͼÏñµÄMNISTѵÁ·Êý¾Ý¼¯ÉÏѵÁ·Ä£ÐÍ¡£Ñ§Êõ½çµ±ÏÂʹÓÃ×î¹ã·ºµÄ´ó¹æÄ£Í¼ÏñÊý¾Ý¼¯ImageNet£¬ËüÓг¬¹ý1,000ÍòµÄͼÏñºÍ1,000ÀàµÄÎïÌ塣Ȼ¶ø£¬ÎÒÃÇÆ½³£½Ó´¥µ½Êý¾Ý¼¯µÄ¹æÄ£Í¨³£ÔÚÕâÁ½ÕßÖ®¼ä¡£¼ÙÉèÎÒÃÇÏë´ÓͼÏñÖÐʶ±ð³ö²»Í¬ÖÖÀàµÄÒÎ×Ó£¬È»ºó½«¹ºÂòÁ´½ÓÍÆ¼ö¸øÓû§¡£Ò»ÖÖ¿ÉÄܵķ½·¨ÊÇÏÈÕÒ³ö100ÖÖ³£¼ûµÄÒÎ×Ó£¬ÎªÃ¿ÖÖÒÎ×ÓÅÄÉã1,000ÕŲ»Í¬½Ç¶ÈµÄͼÏñ£¬È»ºóÔÚÊÕ¼¯µ½µÄͼÏñÊý¾Ý¼¯ÉÏѵÁ·Ò»¸ö·ÖÀàÄ£ÐÍ¡£ÁíÍâÒ»ÖÖ½â¾ö°ì·¨ÊÇÓ¦ÓÃÇ¨ÒÆÑ§Ï°(transfer learning)£¬½«´ÓÔ´Êý¾Ý¼¯Ñ§µ½µÄÖªÊ¶Ç¨ÒÆµ½Ä¿±êÊý¾Ý¼¯ÉÏ¡£ÀýÈ磬ËäÈ»ImageNetÊý¾Ý¼¯µÄͼÏñ´ó¶à¸úÒÎ×ÓÎ޹أ¬µ«ÔÚ¸ÃÊý¾Ý¼¯ÉÏѵÁ·µÄÄ£ÐÍ¿ÉÒÔ³éÈ¡½ÏͨÓõÄͼÏñÌØÕ÷£¬´Ó¶øÄܹ»°ïÖúʶ±ð±ßÔµ¡¢ÎÆÀí¡¢ÐÎ×´ºÍÎïÌå×é³ÉµÈ¡£ÕâЩÀàËÆµÄÌØÕ÷¶ÔÓÚʶ±ðÒÎ×ÓÒ²¿ÉÄÜͬÑùÓÐЧ¡£
΢µ÷ÓÉÒÔÏÂ4²½¹¹³É¡£
1.ÔÚÔ´Êý¾Ý¼¯(ÈçImageNetÊý¾Ý¼¯)ÉÏԤѵÁ·Ò»¸öÉñ¾ÍøÂçÄ£ÐÍ£¬¼´Ô´Ä£ÐÍ¡£
2.´´½¨Ò»¸öеÄÉñ¾ÍøÂçÄ£ÐÍ£¬¼´Ä¿±êÄ£ÐÍ¡£Ëü¸´ÖÆÁËÔ´Ä£ÐÍÉϳýÁËÊä³ö²ãÍâµÄËùÓÐÄ£ÐÍÉè¼Æ¼°Æä²ÎÊý¡£ÎÒÃǼÙÉèÕâЩģÐͲÎÊý°üº¬ÁËÔ´Êý¾Ý¼¯ÉÏѧϰµ½µÄ֪ʶ£¬ÇÒÕâЩ֪ʶͬÑùÊÊÓÃÓÚÄ¿±êÊý¾Ý¼¯¡£ÎÒÃÇ»¹¼ÙÉèÔ´Ä£Ð͵ÄÊä³ö²ã¸úÔ´Êý¾Ý¼¯µÄ±êÇ©½ôÃÜÏà¹Ø£¬Òò´ËÔÚÄ¿±êÄ£ÐÍÖв»Óè²ÉÓá£
3.ΪĿ±êÄ£ÐÍÌí¼ÓÒ»¸öÊä³ö´óСΪĿ±êÊý¾Ý¼¯Àà±ð¸öÊýµÄÊä³ö²ã£¬²¢Ëæ»ú³õʼ»¯¸Ã²ãµÄÄ£ÐͲÎÊý¡£
4.ÔÚÄ¿±êÊý¾Ý¼¯(ÈçÒÎ×ÓÊý¾Ý¼¯)ÉÏѵÁ·Ä¿±êÄ£ÐÍ¡£ÎÒÃǽ«´ÓͷѵÁ·Êä³ö²ã£¬¶øÆäÓà²ãµÄ²ÎÊý¶¼ÊÇ»ùÓÚÔ´Ä£Ð͵IJÎÊý΢µ÷µÃµ½µÄ¡£

µ±Ä¿±êÊý¾Ý¼¯Ô¶Ð¡ÓÚÔ´Êý¾Ý¼¯Ê±£¬Î¢µ÷ÓÐÖúÓÚÌáÉýÄ£Ð͵ķº»¯ÄÜÁ¦¡£
½ÓÏÂÀ´ÎÒÃÇÀûÓÃ΢µ÷Ä£ÐÍÀ´Êµ¼ùÒ»¸ö¾ßÌåµÄÀý×Ó£ºÈȹ·Ê¶±ð¡£½«»ùÓÚÒ»¸öСÊý¾Ý¼¯¶ÔÔÚImageNetÊý¾Ý¼¯ÉÏѵÁ·ºÃµÄResNetÄ£ÐͽøÐÐ΢µ÷¡£¸ÃСÊý¾Ý¼¯º¬ÓÐÊýǧÕÅÈȹ·»òÕ߯äËûÊÂÎïµÄͼÏñ¡£ÎÒÃǽ«Ê¹ÓÃ΢µ÷µÃµ½µÄÄ£ÐÍÀ´Ê¶±ðÒ»ÕÅͼÏñÖÐÊÇ·ñ°üº¬Èȹ·¡£
Ê×ÏÈ£¬µ¼ÈëʵÑéËùÐèµÄ¹¤¾ß°ü¡£
import tensorflow as tf import numpy as np
ÎÒÃÇÊ×ÏȽ«Êý¾Ý¼¯·ÅÔÚ·¾¶hotdog/dataÖ®ÏÂ:

ÿ¸öÀà±ðÎļþ¼ÐÀïÃæÊÇͼÏñÎļþ¡£
ÉÏÒ»½ÚÖÐÎÒÃǽéÉÜÁËImageDataGenerator½øÐÐͼÏñÔöÇ¿£¬ÎÒÃÇ¿ÉÒÔͨ¹ýÒÔÏ·½·¨¶ÁȡͼÏñÎļþ£¬¸Ã·½·¨ÒÔÎļþ¼Ð·¾¶Îª²ÎÊý,Éú³É¾¹ýͼÏñÔöÇ¿ºóµÄ½á¹û£¬²¢²úÉúbatchÊý¾Ý£º
flow_from_directory(self, directory,
target_size=(256, 256), color_mode='rgb',
classes=None, class_mode='categorical',
batch_size=32, shuffle=True, seed=None,
save_to_dir=None£©
Ö÷Òª²ÎÊý£º
directory: Ä¿±êÎļþ¼Ð·¾¶£¬¶ÔÓÚÿһ¸öÀà¶ÔÓ¦Ò»¸ö×ÓÎļþ¼Ð£¬¸Ã×ÓÎļþ¼ÐÖÐÈκÎJPG¡¢PNG¡¢BNP¡¢PPMµÄͼƬ¶¼¿ÉÒÔ¶ÁÈ¡¡£
target_size: ĬÈÏΪ(256, 256)£¬Í¼Ïñ½«±»resize³É¸Ã³ß´ç¡£
batch_size: batchÊý¾ÝµÄ´óС£¬Ä¬ÈÏ32¡£
shuffle: ÊÇ·ñ´òÂÒÊý¾Ý£¬Ä¬ÈÏΪTrue¡£
ÎÒÃÇ´´½¨Á½¸ötf.keras.preprocessing.image.ImageDataGeneratorʵÀýÀ´·Ö±ð¶ÁȡѵÁ·Êý¾Ý¼¯ºÍ²âÊÔÊý¾Ý¼¯ÖеÄËùÓÐͼÏñÎļþ¡£½«ÑµÁ·¼¯Í¼Æ¬È«²¿´¦ÀíΪ¸ßºÍ¿í¾ùΪ224ÏñËØµÄÊäÈë¡£´ËÍ⣬ÎÒÃǶÔRGB(ºì¡¢ÂÌ¡¢À¶)Èý¸öÑÕɫͨµÀµÄÊýÖµ×ö±ê×¼»¯¡£
# »ñÈ¡Êý¾Ý¼¯
import pathlib
train_dir = 'transferdata/train'
test_dir = 'transferdata/test'
# »ñȡѵÁ·¼¯Êý¾Ý
train_dir = pathlib.Path(train_dir)
train_count = len(list(train_dir.glob('*/*.jpg')))
# »ñÈ¡²âÊÔ¼¯Êý¾Ý
test_dir = pathlib.Path(test_dir)
test_count = len(list(test_dir.glob('*/*.jpg')))
# ´´½¨imageDataGenerator½øÐÐͼÏñ´¦Àí
image_generator = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1./255)
# ÉèÖòÎÊý
BATCH_SIZE = 32
IMG_HEIGHT = 224
IMG_WIDTH = 224
# »ñȡѵÁ·Êý¾Ý
train_data_gen = image_generator.flow_from_directory(directory=str(train_dir),
batch_size=BATCH_SIZE,
target_size=(IMG_HEIGHT, IMG_WIDTH),
shuffle=True)
# »ñÈ¡²âÊÔÊý¾Ý
test_data_gen = image_generator.flow_from_directory(directory=str(test_dir),
batch_size=BATCH_SIZE,
target_size=(IMG_HEIGHT, IMG_WIDTH),
shuffle=True)
ÏÂÃæÎÒÃÇËæ»úÈ¡1¸öbatchµÄͼƬȻºó»æÖƳöÀ´¡£
import matplotlib.pyplot as plt
# ÏÔʾͼÏñ
def show_batch(image_batch, label_batch):
plt.figure(figsize=(10,10))
for n in range(15):
ax = plt.subplot(5,5,n+1)
plt.imshow(image_batch[n]£©
plt.axis('off')
# Ëæ»úÑ¡ÔñÒ»¸öbatchµÄͼÏñ
image_batch, label_batch = next(train_data_gen)
# ͼÏñÏÔʾ
show_batch(image_batch, label_batch)

ÎÒÃÇʹÓÃÔÚImageNetÊý¾Ý¼¯ÉÏԤѵÁ·µÄResNet-50×÷ΪԴģÐÍ¡£ÕâÀïÖ¸¶¨weights='imagenet'À´×Ô¶¯ÏÂÔØ²¢¼ÓÔØÔ¤ÑµÁ·µÄÄ£ÐͲÎÊý¡£ÔÚµÚÒ»´ÎʹÓÃʱÐèÒªÁªÍøÏÂÔØÄ£ÐͲÎÊý¡£
KerasÓ¦ÓóÌÐò(keras.applications)ÊǾßÓÐÔ¤ÏÈѵÁ·È¨ÖµµÄ¹Ì¶¨¼Ü¹¹£¬¸ÃÀà·â×°Á˺ܶàÖØÁ¿¼¶µÄÍøÂç¼Ü¹¹£¬ÈçÏÂͼËùʾ£º

ʵÏÖʱʵÀý»¯Ä£Ðͼܹ¹£º
tf.keras.applications.ResNet50(
include_top=True, weights='imagenet', input_tensor=None, input_shape=None,
pooling=None, classes=1000, **kwargs)
Ö÷Òª²ÎÊý£º
include_top: ÊÇ·ñ°üÀ¨¶¥²ãµÄÈ«Á¬½Ó²ã¡£
weights: None ´ú±íËæ»ú³õʼ»¯£¬ 'imagenet' ´ú±í¼ÓÔØÔÚ ImageNet ÉÏԤѵÁ·µÄȨֵ¡£
input_shape: ¿ÉÑ¡£¬ÊäÈë³ß´çÔª×飬½öµ± include_top=False ʱÓÐЧ£¬·ñÔòÊäÈëÐÎ×´±ØÐëÊÇ (224, 224, 3)(channels_last ¸ñʽ)»ò (3, 224, 224)(channels_first ¸ñʽ)¡£Ëü±ØÐëΪ 3 ¸öÊäÈëͨµÀ£¬ÇÒ¿í¸ß±ØÐ벻СÓÚ 32£¬±ÈÈç (200, 200, 3) ÊÇÒ»¸öºÏ·¨µÄÊäÈë³ß´ç¡£
Ôڸð¸ÀýÖÐÎÒÃÇʹÓÃresNet50ԤѵÁ·Ä£Ð͹¹½¨Ä£ÐÍ£º
# ¼ÓÔØÔ¤ÑµÁ·Ä£ÐÍ
ResNet50 = tf.keras.applications.ResNet50(weights='imagenet', input_shape=(224,224,3))
# ÉèÖÃËùÓв㲻¿ÉѵÁ·
for layer in ResNet50.layers:
layer.trainable = False
# ÉèÖÃÄ£ÐÍ
net = tf.keras.models.Sequential()
# ԤѵÁ·Ä£ÐÍ
net.add(ResNet50)
# Õ¹¿ª
net.add(tf.keras.layers.Flatten())
# ¶þ·ÖÀàµÄÈ«Á¬½Ó²ã
net.add(tf.keras.layers.Dense(2, activation='softmax'))
½ÓÏÂÀ´ÎÒÃÇʹÓÃ֮ǰ¶¨ÒåºÃµÄImageGenerator½«ÑµÁ·¼¯Í¼Æ¬ËÍÈëResNet50½øÐÐѵÁ·¡£
# Ä£ÐͱàÒ룺ָ¶¨ÓÅ»¯Æ÷£¬Ëðʧº¯ÊýºÍÆÀ¼ÛÖ¸±ê
net.compile(optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy'])
# Ä£ÐÍѵÁ·£ºÖ¸¶¨Êý¾Ý£¬Ã¿Ò»¸öepochÖÐÖ»ÔËÐÐ10¸öµü´ú£¬Ö¸¶¨ÑéÖ¤Êý¾Ý¼¯
history = net.fit(
train_data_gen,
steps_per_epoch=10,
epochs=3,
validation_data=test_data_gen,
validation_steps=10
)
Epoch 1/3 10/10 [==============================] - 28s 3s/step - loss: 0.6931 - accuracy: 0.5031 - val_loss: 0.6930 - val_accuracy: 0.5094 Epoch 2/3 10/10 [==============================] - 29s 3s/step - loss: 0.6932 - accuracy: 0.5094 - val_loss: 0.6935 - val_accuracy: 0.4812 Epoch 3/3 10/10 [==============================] - 31s 3s/step - loss: 0.6935 - accuracy: 0.4844 - val_loss: 0.6933 - val_accuracy: 0.4875
±±¾©Ð£Çø