赞
踩
具体可以参考这篇文章
- import warnings
- warnings.filterwarnings("ignore")
- import os
- os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
-
- from tensorflow.keras.layers import (Conv2D,MaxPool2D,Input,ZeroPadding2D,
- Add,AveragePooling2D,Dense,Flatten,BatchNormalization,
- )
- from tensorflow.keras.models import Model
-
-
-
- def conv_block(inputs,block_id:str,filter_num,stride=1):
- """ 从conv3_x开始,第1个1*1卷积需要下采样 """
- if (block_id[0]!='1' and block_id[2]=='1'):
- stride = 2
- bottle_conv1 = Conv2D(filter_num,1,stride,activation='relu',name="block"+block_id+"_conv1")(inputs)
- bottle_conv1 = BatchNormalization()(bottle_conv1)
- bottle_conv2 = Conv2D(filter_num,3,1,activation='relu',name="block"+block_id+"_conv2")(bottle_conv1)
- bottle_conv2 = BatchNormalization()(bottle_conv2)
- bottle_conv3 = Conv2D(filter_num*4,1,1,activation='relu',name="block"+block_id+"_conv3")(bottle_conv2)
- bottle_conv3 = BatchNormalization()(bottle_conv3)
- bottle_conv3_pad = ZeroPadding2D((1,1),name="block"+block_id+"_conv3Pad")(bottle_conv3)
-
- """ 从conv3_x开始,第1个1*1卷积需要下采样与输出进行堆叠 """
- inputs_conv = Conv2D(filter_num*4,1,stride,activation='relu',name='block'+block_id+"_conv4")(inputs)
- inputs_conv = BatchNormalization()(inputs_conv)
- # print(block_id,bottle_conv3.shape,inputs_conv.shape)
- bottle_out = Add()([bottle_conv3_pad,inputs_conv])
-
- return bottle_out
-
-
- def RESNET50(input_shape=(224,224,3),num_classes=1000):
- inputs = Input(shape=input_shape)
- inputsPad = ZeroPadding2D((3,3))(inputs) # 多出
- conv1 = Conv2D(64,7,2,activation='relu',name='conv1')(inputsPad)
- conv1 = BatchNormalization()(conv1)
- conv2_x_1 = MaxPool2D((3,3),2,padding='same',name='conv2_x_maxpooling')(conv1) # 注意padding
-
- print('conv2_x start...')
- filter_nums0 = 64
- BLOCK1_out = conv2_x_1
- for i in range(1,4):
- BLOCK1_out = conv_block(BLOCK1_out,f"1_{i}",filter_nums0)
-
- print('conv2_x done!')
- print(BLOCK1_out.shape)
-
-
- print('conv3_x start...')
- filter_nums1 = 128
- # remind downsampling
- BLOCK2_out = BLOCK1_out
- for i in range(1,5):
- BLOCK2_out = conv_block(BLOCK2_out,f"2_{i}",filter_nums1)
-
- print('conv3_x done!')
- print(BLOCK2_out.shape)
-
- print('conv4_x start...')
- filter_num2 = 256
- # remind downsampling
- BLOCK3_out = BLOCK2_out
- for i in range(1,7):
- BLOCK3_out = conv_block(BLOCK3_out,f"3_{i}",filter_num2)
- print('conv4_x done!')
- print(BLOCK3_out.shape)
-
- print('conv5_x start...')
- filter_num3 = 512
- # remind downsampling
- BLOCK4_out = BLOCK3_out
- for i in range(1,4):
- BLOCK4_out = conv_block(BLOCK4_out,f"4_{i}",filter_num3)
- print('conv5_x done!')
- print(BLOCK4_out.shape)
-
- avgPooling = AveragePooling2D(BLOCK4_out.shape[1],name='average_pool')(BLOCK4_out)
- x = Flatten()(avgPooling)
- outlayer = Dense(num_classes,activation='softmax',name='out_layer')(x)
- print('out shape:',outlayer.shape)
-
- model = Model(inputs=inputs,outputs=outlayer,name='resnet50-tf2')
- # model.load_weights("resnet50_weights_tf_dim_ordering_tf_kernels.h5")
-
- return model
-
-
- # model = RESNET50(num_classes=2)
- # model.summary()
- # print(f"layer's length={len(model.layers)}")
- # for i,layer in enumerate(model.layers):
- # print(i,layer.name)
-
-
如下面的图所示,将数据分成和文件夹,每个文件夹里面分成和
细节都写在注释里了,有不懂的地方可以留言
- from resnet50 import RESNET50
- from tensorflow.keras.optimizers import Adam
- from tensorflow.keras.callbacks import (ModelCheckpoint,TensorBoard)
- import tensorflow as tf
- import os
- from tensorflow.keras.optimizers.schedules import ExponentialDecay
- from tensorflow.keras.preprocessing.image import ImageDataGenerator
-
-
-
- if __name__ == '__main__':
- print('这条线以下是输出'.center(62,'-'))
-
- model = RESNET50(num_classes=2) # cat,dog
-
- INIT_LEARNING_RATE = 0.001
- # 学习率指数衰减
- learningRateDecay = ExponentialDecay(initial_learning_rate=INIT_LEARNING_RATE,
- decay_steps=2000,decay_rate=0.96)
- adam = Adam(learning_rate=learningRateDecay)
- model.compile(optimizer=adam,loss='categorical_crossentropy',metrics=['acc'])
- # model.load_weights("logs/EP058_acc0.022-vac0.490.h5") 这个可以从断点处继续训练
-
- """ 数据 """
- bs = 30
- train_dir = "datasets/train/"
- val_dir = "datasets/test/"
- train_datagen = ImageDataGenerator(rescale=1.0/255.0)
- val_datagen = ImageDataGenerator(rescale=1.0/255.0)
-
- train_generator = train_datagen.flow_from_directory(train_dir,batch_size=bs,
- class_mode='categorical',
- target_size=(224,224))
- val_generator = val_datagen.flow_from_directory(val_dir,batch_size=bs,
- class_mode='categorical',
- target_size=(224,224))
-
-
- # 设置checkpoint
- logdir = 'logs/'
- if not os.path.exists(logdir):
- os.mkdir(logdir)
- checkpoint_path = logdir + "EP{epoch:03d}_loss{loss:.3f}-valoss{val_loss:.3f}.h5"
- checkpoint_dir = os.path.dirname(checkpoint_path)
- cp_callback = ModelCheckpoint(filepath=checkpoint_path,
- save_weights_only=True,verbose=1)
-
- # 设置tensorboard
- tensorboard_callback = TensorBoard(log_dir=logdir, histogram_freq=1)
-
- # 训练
- epochs = 100
- model.fit(train_generator,
- validation_data=val_generator,
- epochs=epochs,
- callbacks=[cp_callback,tensorboard_callback])
-
-
- print('输出完毕'.center(66,'-'))
可以通过 tensorboard --logdir=logs --host=localhost 查看训练情况:
训练好的权重文件会保存在logs文件夹里面:
一般挑最后一个进行预测。其中注意要将传入预测的图片进行和训练时一样的预处理,具体包括:①reshape,②expand_dims,③归一化
- from resnet50 import RESNET50
- import cv2
- import numpy as np
- import time
- import matplotlib.pyplot as plt
-
- if __name__ == '__main__':
- print('这条线以下是输出'.center(62,'-'))
-
- classes_name = ['cat',"dog"]
- input_shape = (224,224)
-
- print('predict start...'.center(66,'-'))
- model = RESNET50(num_classes=len(classes_name))
- model.load_weights("logs/EP039_loss0.019-valoss0.295.h5")
- print(f'load weights successfully!')
-
- figure = plt.figure(figsize=(6,4),dpi=200)
- for i,filename in enumerate(['testCat1.jpg','testCat2.jpg',
- 'testDog.jpg','testDog2.jpg']):
- start = time.time()
- inputs = cv2.imread(filename)
- inputs = cv2.resize(inputs,input_shape).astype(np.float32)
- inputs0 = np.array(inputs, dtype="float") / 255.0
- inputs = np.expand_dims(inputs0,axis=0)
- # print(inputs.shape)
- # print(inputs)
-
- outputs = model.predict(inputs)
- print(outputs)
- result_index = np.argmax(outputs)
- result = classes_name[result_index]
- print(f"图片是{result}")
- print(f'花费时间{time.time()-start:.2f}s')
-
- plt.subplot(2,2,i+1)
- plt.title(result)
- plt.axis('off')
- plt.imshow(inputs0[...,::-1])
-
-
- plt.show()
- print('输出完毕'.center(66,'-'))
我到网上下了2张猫和狗的图片进行测试:
最后将预测结果通过画图显示出来,以预测结果作为图像的title:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。