当前位置:   article > 正文

tensorflow2实现resnet50并用来分类猫狗_tensorflow2 keras resnet50

tensorflow2 keras resnet50

一、首先实现resnet50

具体可以参考这篇文章

  1. import warnings
  2. warnings.filterwarnings("ignore")
  3. import os
  4. os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
  5. from tensorflow.keras.layers import (Conv2D,MaxPool2D,Input,ZeroPadding2D,
  6. Add,AveragePooling2D,Dense,Flatten,BatchNormalization,
  7. )
  8. from tensorflow.keras.models import Model
  9. def conv_block(inputs,block_id:str,filter_num,stride=1):
  10. """ 从conv3_x开始,第1个1*1卷积需要下采样 """
  11. if (block_id[0]!='1' and block_id[2]=='1'):
  12. stride = 2
  13. bottle_conv1 = Conv2D(filter_num,1,stride,activation='relu',name="block"+block_id+"_conv1")(inputs)
  14. bottle_conv1 = BatchNormalization()(bottle_conv1)
  15. bottle_conv2 = Conv2D(filter_num,3,1,activation='relu',name="block"+block_id+"_conv2")(bottle_conv1)
  16. bottle_conv2 = BatchNormalization()(bottle_conv2)
  17. bottle_conv3 = Conv2D(filter_num*4,1,1,activation='relu',name="block"+block_id+"_conv3")(bottle_conv2)
  18. bottle_conv3 = BatchNormalization()(bottle_conv3)
  19. bottle_conv3_pad = ZeroPadding2D((1,1),name="block"+block_id+"_conv3Pad")(bottle_conv3)
  20. """ 从conv3_x开始,第1个1*1卷积需要下采样与输出进行堆叠 """
  21. inputs_conv = Conv2D(filter_num*4,1,stride,activation='relu',name='block'+block_id+"_conv4")(inputs)
  22. inputs_conv = BatchNormalization()(inputs_conv)
  23. # print(block_id,bottle_conv3.shape,inputs_conv.shape)
  24. bottle_out = Add()([bottle_conv3_pad,inputs_conv])
  25. return bottle_out
  26. def RESNET50(input_shape=(224,224,3),num_classes=1000):
  27. inputs = Input(shape=input_shape)
  28. inputsPad = ZeroPadding2D((3,3))(inputs) # 多出
  29. conv1 = Conv2D(64,7,2,activation='relu',name='conv1')(inputsPad)
  30. conv1 = BatchNormalization()(conv1)
  31. conv2_x_1 = MaxPool2D((3,3),2,padding='same',name='conv2_x_maxpooling')(conv1) # 注意padding
  32. print('conv2_x start...')
  33. filter_nums0 = 64
  34. BLOCK1_out = conv2_x_1
  35. for i in range(1,4):
  36. BLOCK1_out = conv_block(BLOCK1_out,f"1_{i}",filter_nums0)
  37. print('conv2_x done!')
  38. print(BLOCK1_out.shape)
  39. print('conv3_x start...')
  40. filter_nums1 = 128
  41. # remind downsampling
  42. BLOCK2_out = BLOCK1_out
  43. for i in range(1,5):
  44. BLOCK2_out = conv_block(BLOCK2_out,f"2_{i}",filter_nums1)
  45. print('conv3_x done!')
  46. print(BLOCK2_out.shape)
  47. print('conv4_x start...')
  48. filter_num2 = 256
  49. # remind downsampling
  50. BLOCK3_out = BLOCK2_out
  51. for i in range(1,7):
  52. BLOCK3_out = conv_block(BLOCK3_out,f"3_{i}",filter_num2)
  53. print('conv4_x done!')
  54. print(BLOCK3_out.shape)
  55. print('conv5_x start...')
  56. filter_num3 = 512
  57. # remind downsampling
  58. BLOCK4_out = BLOCK3_out
  59. for i in range(1,4):
  60. BLOCK4_out = conv_block(BLOCK4_out,f"4_{i}",filter_num3)
  61. print('conv5_x done!')
  62. print(BLOCK4_out.shape)
  63. avgPooling = AveragePooling2D(BLOCK4_out.shape[1],name='average_pool')(BLOCK4_out)
  64. x = Flatten()(avgPooling)
  65. outlayer = Dense(num_classes,activation='softmax',name='out_layer')(x)
  66. print('out shape:',outlayer.shape)
  67. model = Model(inputs=inputs,outputs=outlayer,name='resnet50-tf2')
  68. # model.load_weights("resnet50_weights_tf_dim_ordering_tf_kernels.h5")
  69. return model
  70. # model = RESNET50(num_classes=2)
  71. # model.summary()
  72. # print(f"layer's length={len(model.layers)}")
  73. # for i,layer in enumerate(model.layers):
  74. # print(i,layer.name)

二、准备数据

如下面的图所示,将数据分成traintest文件夹,每个文件夹里面分成dogcat

三、写训练文件

细节都写在注释里了,有不懂的地方可以留言

  1. from resnet50 import RESNET50
  2. from tensorflow.keras.optimizers import Adam
  3. from tensorflow.keras.callbacks import (ModelCheckpoint,TensorBoard)
  4. import tensorflow as tf
  5. import os
  6. from tensorflow.keras.optimizers.schedules import ExponentialDecay
  7. from tensorflow.keras.preprocessing.image import ImageDataGenerator
  8. if __name__ == '__main__':
  9. print('这条线以下是输出'.center(62,'-'))
  10. model = RESNET50(num_classes=2) # cat,dog
  11. INIT_LEARNING_RATE = 0.001
  12. # 学习率指数衰减
  13. learningRateDecay = ExponentialDecay(initial_learning_rate=INIT_LEARNING_RATE,
  14. decay_steps=2000,decay_rate=0.96)
  15. adam = Adam(learning_rate=learningRateDecay)
  16. model.compile(optimizer=adam,loss='categorical_crossentropy',metrics=['acc'])
  17. # model.load_weights("logs/EP058_acc0.022-vac0.490.h5") 这个可以从断点处继续训练
  18. """ 数据 """
  19. bs = 30
  20. train_dir = "datasets/train/"
  21. val_dir = "datasets/test/"
  22. train_datagen = ImageDataGenerator(rescale=1.0/255.0)
  23. val_datagen = ImageDataGenerator(rescale=1.0/255.0)
  24. train_generator = train_datagen.flow_from_directory(train_dir,batch_size=bs,
  25. class_mode='categorical',
  26. target_size=(224,224))
  27. val_generator = val_datagen.flow_from_directory(val_dir,batch_size=bs,
  28. class_mode='categorical',
  29. target_size=(224,224))
  30. # 设置checkpoint
  31. logdir = 'logs/'
  32. if not os.path.exists(logdir):
  33. os.mkdir(logdir)
  34. checkpoint_path = logdir + "EP{epoch:03d}_loss{loss:.3f}-valoss{val_loss:.3f}.h5"
  35. checkpoint_dir = os.path.dirname(checkpoint_path)
  36. cp_callback = ModelCheckpoint(filepath=checkpoint_path,
  37. save_weights_only=True,verbose=1)
  38. # 设置tensorboard
  39. tensorboard_callback = TensorBoard(log_dir=logdir, histogram_freq=1)
  40. # 训练
  41. epochs = 100
  42. model.fit(train_generator,
  43. validation_data=val_generator,
  44. epochs=epochs,
  45. callbacks=[cp_callback,tensorboard_callback])
  46. print('输出完毕'.center(66,'-'))

可以通过 tensorboard --logdir=logs --host=localhost 查看训练情况:

 

四、写预测文件

训练好的权重文件会保存在logs文件夹里面:

 

一般挑最后一个进行预测。其中注意要将传入预测的图片进行和训练时一样的预处理,具体包括:①reshape,②expand_dims,③归一化

  1. from resnet50 import RESNET50
  2. import cv2
  3. import numpy as np
  4. import time
  5. import matplotlib.pyplot as plt
  6. if __name__ == '__main__':
  7. print('这条线以下是输出'.center(62,'-'))
  8. classes_name = ['cat',"dog"]
  9. input_shape = (224,224)
  10. print('predict start...'.center(66,'-'))
  11. model = RESNET50(num_classes=len(classes_name))
  12. model.load_weights("logs/EP039_loss0.019-valoss0.295.h5")
  13. print(f'load weights successfully!')
  14. figure = plt.figure(figsize=(6,4),dpi=200)
  15. for i,filename in enumerate(['testCat1.jpg','testCat2.jpg',
  16. 'testDog.jpg','testDog2.jpg']):
  17. start = time.time()
  18. inputs = cv2.imread(filename)
  19. inputs = cv2.resize(inputs,input_shape).astype(np.float32)
  20. inputs0 = np.array(inputs, dtype="float") / 255.0
  21. inputs = np.expand_dims(inputs0,axis=0)
  22. # print(inputs.shape)
  23. # print(inputs)
  24. outputs = model.predict(inputs)
  25. print(outputs)
  26. result_index = np.argmax(outputs)
  27. result = classes_name[result_index]
  28. print(f"图片是{result}")
  29. print(f'花费时间{time.time()-start:.2f}s')
  30. plt.subplot(2,2,i+1)
  31. plt.title(result)
  32. plt.axis('off')
  33. plt.imshow(inputs0[...,::-1])
  34. plt.show()
  35. print('输出完毕'.center(66,'-'))

我到网上下了2张猫和狗的图片进行测试:

最后将预测结果通过画图显示出来,以预测结果作为图像的title:

 这样,我们就走完了图像分类的所有流程了,如果对您有帮助,就点个赞吧,谢谢!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/92790
推荐阅读
相关标签
  

闽ICP备14008679号