paddle实现GoogLeNet-InceptionV1

Vicki ·
更新时间:2024-09-21
· 908 次阅读

GoogLeNet Inception v1 结构 及 pytorch、tensorflow、keras、paddle实现ImageNet识别

环境

python3.6, paddlepaddle-gpu 1.6.3.post107

代码

# -*- coding: utf-8 -*- # @Time : 2020/2/3 9:56 # @Author : Zhao HL # @File : InceptionV1-paddle.py import os, sys from PIL import Image import numpy as np import pandas as pd import paddle from paddle import fluid from paddle.fluid.layers import data, conv2d, pool2d, flatten, fc, cross_entropy, accuracy, mean, concat, dropout from my_utils import process_show, draw_loss_acc # region parameters # region paths Data_path = "./data/" Data_csv_path = "./data/split.txt" Model_path = 'model/' Model_file_tf = "model/InceptionV1_tf.ckpt" Model_file_keras = "model/InceptionV1_keras.h5" Model_file_torch = "model/InceptionV1_torch.pth" Model_file_paddle = "model/InceptionV1_paddle.model" # endregion # region image parameter Img_size = 224 Img_chs = 3 Label_size = 1 Label_class = ['agricultural', 'airplane', 'baseballdiamond', 'beach', 'buildings', 'chaparral', 'denseresidential', 'forest', 'freeway', 'golfcourse', 'harbor', 'intersection', 'mediumresidential', 'mobilehomepark', 'overpass', 'parkinglot', 'river', 'runway', 'sparseresidential', 'storagetanks', 'tenniscourt'] Labels_nums = len(Label_class) # endregion # region net parameter Conv1_kernel_size = 7 Conv1_chs = 64 Conv21_kernel_size = 1 Conv21_chs = 64 Conv2_kernel_size = 3 Conv2_chs = 192 Icp3a_size = (64, 96, 128, 16, 32, 32) Icp3b_size = (128, 128, 192, 32, 96, 64) Icp4a_size = (192, 96, 208, 16, 48, 64) Icp4b_size = (160, 112, 224, 24, 64, 64) Icp4c_size = (128, 128, 256, 24, 64, 64) Icp4d_size = (112, 144, 288, 32, 64, 64) Icp4e_size = (256, 160, 320, 32, 128, 128) Icp5a_size = (256, 160, 320, 32, 128, 128) Icp5b_size = (384, 192, 384, 48, 128, 128) Out_chs1 = 128 Out_chs2 = 1024 # endregion # region hpyerparameter Learning_rate = 1e-3 Batch_size = 16 Buffer_size = 256 Infer_size = 1 Epochs = 20 Train_num = 1470 Train_batch_num = Train_num // Batch_size Val_num = 210 Val_batch_num = Val_num // Batch_size Test_num = 420 Test_batch_num = Test_num // Batch_size # endregion place = fluid.CUDAPlace(0) if fluid.cuda_places() else fluid.CPUPlace() # endregion class MyDataset(): def __init__(self, root_path, batch_size, files_list=None, ): self.root_path = root_path self.files_list = files_list if files_list else os.listdir(root_path) self.size = len(files_list) self.batch_size = batch_size def __len__(self): return self.size def dataset_reader(self): pass files_list = self.files_list if self.files_list is not None else os.listdir(self.root_path) def reader(): np.random.shuffle(files_list) for file_name in files_list: label_str = os.path.basename(file_name)[:-6] label = Label_class.index(label_str) img = Image.open(os.path.join(self.root_path, file_name)) yield img, label return paddle.batch(paddle.reader.xmap_readers(self.transform, reader, 2, Buffer_size), batch_size=self.batch_size) def transform(self, sample): def Normalize(image, means, stds): for band in range(len(means)): image[:, :, band] = image[:, :, band] / 255.0 image[:, :, band] = (image[:, :, band] - means[band]) / stds[band] image = np.transpose(image, [2, 1, 0]) return image pass image, label = sample image = image.resize((Img_size, Img_size), Image.ANTIALIAS) image = Normalize(np.array(image).astype(np.float), [0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) return image, label class InceptionV1: def __init__(self, structShow=False): self.structShow = structShow self.image = data(shape=[Img_chs, Img_size, Img_size], dtype='float32', name='image') self.label = data(shape=[Label_size], dtype='int64', name='label') self.predict = self.get_Net() def InceptionV1_Model(self, input, model_size): con11_chs, con31_chs, con3_chs, con51_chs, con5_chs, pool1_chs = model_size conv11 = conv2d(input, con11_chs, filter_size=1, padding='SAME', act='relu') conv31 = conv2d(input, con31_chs, filter_size=1, padding='SAME', act='relu') conv3 = conv2d(conv31, con3_chs, filter_size=3, padding='SAME', act='relu') conv51 = conv2d(input, con51_chs, filter_size=1, padding='SAME', act='relu') conv5 = conv2d(conv51, con5_chs, filter_size=5, padding='SAME', act='relu') pool1 = pool2d(input, pool_size=3, pool_stride=1, pool_type='max', pool_padding='SAME') conv1 = conv2d(pool1, pool1_chs, filter_size=1, padding='SAME', act='relu') output = concat([conv11, conv3, conv5, conv1], axis=1) return output def InceptionV1_Out(self, input, name=None): pool = pool2d(input, pool_size=5, pool_stride=3, pool_type='avg', pool_padding='VALID') conv = conv2d(pool, Out_chs1, filter_size=1, padding='SAME', act='relu') flat = flatten(conv, axis=1) dp = dropout(flat, 0.3) output = fc(dp, Labels_nums, name=name) return output def get_Net(self): # region conv pool conv1 = conv2d(self.image, Conv1_chs, filter_size=Conv1_kernel_size, stride=2, padding='SAME', act='relu') pool1 = pool2d(conv1, pool_size=3, pool_stride=2, pool_type='max', pool_padding='SAME') conv21 = conv2d(pool1, Conv21_chs, filter_size=Conv21_kernel_size, padding='SAME', act='relu') conv2 = conv2d(conv21, Conv2_chs, filter_size=Conv2_kernel_size, padding='SAME', act='relu') pool2 = pool2d(conv2, pool_size=3, pool_stride=2, pool_type='max', pool_padding='SAME') # endregion # region inception3 inception3a = self.InceptionV1_Model(pool2, Icp3a_size) inception3b = self.InceptionV1_Model(inception3a, Icp3b_size) pool3 = pool2d(inception3b, pool_size=3, pool_stride=2, pool_type='max', pool_padding='SAME') # endregion # region inception3 inception4a = self.InceptionV1_Model(pool3, Icp4a_size) output1 = self.InceptionV1_Out(inception4a, 'output1') inception4b = self.InceptionV1_Model(inception4a, Icp4b_size) inception4c = self.InceptionV1_Model(inception4b, Icp4c_size) inception4d = self.InceptionV1_Model(inception4c, Icp4d_size) output2 = self.InceptionV1_Out(inception4d, 'output2') inception4e = self.InceptionV1_Model(inception4d, Icp4e_size) pool4 = pool2d(inception4e, pool_size=3, pool_stride=2, pool_type='max', pool_padding='SAME') # endregion # region inception5 inception5a = self.InceptionV1_Model(pool4, Icp5a_size) inception5b = self.InceptionV1_Model(inception5a, Icp5b_size) pool5 = pool2d(inception5b, pool_size=7, pool_stride=1, pool_type='max', pool_padding='SAME') # endregion # region output flat = flatten(pool5, axis=1) dp = dropout(flat, 0.4) output = fc(dp, Labels_nums, name='output') # endregion if self.structShow: print(pool1.name, pool1.shape) print(pool2.name, pool2.shape) print(inception3a.name, inception3a.shape) print(inception3b.name, inception3b.shape) print(pool3.name, pool3.shape) print(inception4a.name, inception4a.shape) print(output1.name, output1.shape) print(inception4b.name, inception4b.shape) print(inception4c.name, inception4c.shape) print(inception4d.name, inception4d.shape) print(output2.name, output2.shape) print(inception4e.name, inception4e.shape) print(pool4.name, pool4.shape) print(inception5a.name, inception5a.shape) print(inception5b.name, inception5b.shape) print(pool5.name, pool5.shape) print(flat.name, flat.shape) print(output.name, output.shape) print(output.name, output.shape) return [output, output1, output2] # return output def train(): net = InceptionV1(structShow=True) image, label, [predict, predict1, predict2] = net.image, net.label, net.predict feeder = fluid.DataFeeder(place=place, feed_list=[image, label]) df = pd.read_csv(Data_csv_path, header=0, index_col=0) train_list = df[df['split'] == 'train']['filename'].tolist() val_list = df[df['split'] == 'val']['filename'].tolist() train_reader = MyDataset(Data_path, batch_size=Batch_size, files_list=train_list).dataset_reader() val_reader = MyDataset(Data_path, batch_size=Batch_size, files_list=val_list).dataset_reader() loss = cross_entropy(input=predict, label=label) loss1 = cross_entropy(input=predict1, label=label) loss2 = cross_entropy(input=predict2, label=label) loss_mean = mean(loss) loss1_mean = mean(loss1) loss2_mean = mean(loss2) loss_total = loss_mean * 0.6 + loss1_mean * 0.2 + loss2_mean * 0.2 acc = accuracy(input=predict, label=label,k=1) optimizer = fluid.optimizer.AdamOptimizer(learning_rate=Learning_rate) optimizer.minimize(loss_total) val_program = fluid.default_main_program().clone(for_test=True) exe = fluid.Executor(place) exe.run(fluid.default_startup_program()) train_losses = np.ones(Epochs) train_accs = np.ones(Epochs) val_losses = np.ones(Epochs) val_accs = np.ones(Epochs) best_loss = float("inf") best_loss_epoch = 0 for epoch in range(Epochs): print('Epoch %d/%d:' % (epoch + 1, Epochs)) train_sum_loss = 0 train_sum_acc = 0 val_sum_loss = 0 val_sum_acc = 0 for batch_num, data in enumerate(train_reader()): train_loss, train_acc = exe.run(program=fluid.default_main_program(), # 运行主程序 feed=feeder.feed(data), # 给模型喂入数据 fetch_list=[loss_total, acc]) # fetch 误差、准确率 train_sum_loss += train_loss[0] train_sum_acc += train_acc[0] process_show(batch_num + 1, Train_num / Batch_size, train_acc, train_loss, prefix='train:') for batch_num, data in enumerate(val_reader()): val_loss, val_acc = exe.run(program=val_program, # 执行训练程序 feed=feeder.feed(data), # 喂入数据 fetch_list=[loss_total, acc]) # fetch 误差、准确率 val_sum_loss += val_loss[0] val_sum_acc += val_acc[0] process_show(batch_num + 1, Val_num / Batch_size, val_acc, val_loss, prefix='train:') train_sum_loss /= (Train_num // Batch_size) train_sum_acc /= (Train_num // Batch_size) val_sum_loss /= (Val_num // Batch_size) val_sum_acc /= (Val_num // Batch_size) train_losses[epoch] = train_sum_loss train_accs[epoch] = train_sum_acc val_losses[epoch] = val_sum_loss val_accs[epoch] = val_sum_acc print('average summary:\ntrain acc %.4f, loss %.4f ; val acc %.4f, loss %.4f' % (train_sum_acc, train_sum_loss, val_sum_acc, val_sum_loss)) if val_sum_loss < best_loss: print('val_loss improve from %.4f to %.4f, model save to %s ! \n' % ( best_loss, val_sum_loss, Model_file_paddle)) best_loss = val_sum_loss best_loss_epoch = epoch + 1 fluid.io.save_inference_model(Model_file_paddle, # 保存推理model的路径 ['image'], # 推理(inference)需要 feed 的数据 [predict], # 保存推理(inference)结果的 Variables exe) # executor 保存 inference model else: print('val_loss do not improve from %.4f \n' % (best_loss)) print('best loss %.4f at epoch %d \n' % (best_loss, best_loss_epoch)) draw_loss_acc(train_losses, train_accs, 'train') draw_loss_acc(val_losses, val_accs, 'val') if __name__ == '__main__': pass train()

my_utils.py

# -*- coding: utf-8 -*- # @Time : 2020/1/21 11:39 # @Author : Zhao HL # @File : my_utils.py import sys,os,random import numpy as np import pandas as pd import matplotlib.pyplot as plt from PIL import Image def process_show(num, nums, train_acc, train_loss, prefix='', suffix=''): rate = num / nums ratenum = int(round(rate, 2) * 100) bar = '\r%s batch %3d/%d:train accuracy %.4f, train loss %00.4f [%s%s]%.1f%% %s; ' % ( prefix, num, nums, train_acc, train_loss, '#' * (ratenum//2), '_' * (50 - ratenum//2), ratenum, suffix) sys.stdout.write(bar) sys.stdout.flush() if num >= nums: print() def dataInfo_show(data_path,csv_pth,cls_dic_path,shapesShow=True,classesShow=True): cls_dict = get_cls_dic(cls_dic_path) if classesShow: print('\n'+'*'*50) df = pd.read_csv(csv_pth) labels = df['label'].unique() label_cls = {label:cls_dict[label] for label in labels} print(label_cls) cls_count = df['label'].value_counts() cls_count = {cls_dict[k]:v for k,v in cls_count.items()} for k,v in cls_count.items(): print(k,v) if shapesShow: print('\n'+'*'*50) shapes = [] for filename in os.listdir(data_path): img = Image.open(os.path.join(data_path, filename)) img = np.array(img) shapes.append(img.shape) shapes = pd.Series(shapes) print(shapes.value_counts()) def get_cls_dic(cls_dic_path): # 读取类标签字典,只取第一个逗号前的信息 cls_df = pd.read_csv(cls_dic_path) cls_df['cls'] = cls_df['info'].apply(lambda x:x[:9]).tolist() cls_df['label'] = cls_df['info'].apply(lambda x: x[10:]).tolist() cls_df = cls_df.drop(columns=['info','other']) cls_dict = cls_df.set_index('cls').T.to_dict('list') cls_dict = {k:v[0] for k,v in cls_dict.items()} return cls_dict def dataset_divide(csv_pth): cls_df = pd.read_csv(csv_pth, header=0,index_col=0) cls_df.insert(1,'split',None) filenames = list(cls_df['filename']) random.shuffle(filenames) train_num,train_val_num = int(len(filenames)*0.7),int(len(filenames)*0.8) train_names = filenames[:train_num] val_names = filenames[train_num:train_val_num] test_names = filenames[train_val_num:] cls_df.loc[cls_df['filename'].isin(train_names),'split'] = 'train' cls_df.loc[cls_df['filename'].isin(val_names), 'split'] = 'val' cls_df.loc[cls_df['filename'].isin(test_names), 'split'] = 'test' cls_df.to_csv(csv_pth) def draw_loss_acc(loss,acc,type='',save_path=None): assert len(acc) == len(loss) x = [epoch for epoch in range(len(acc))] plt.subplot(2, 1, 1) plt.plot(x, acc, 'o-') plt.title(type+' accuracy vs. epoches') plt.ylabel('accuracy') plt.subplot(2, 1, 2) plt.plot(x, loss, '.-') plt.xlabel(type+' loss vs. epoches') plt.ylabel('loss') plt.show() if save_path: plt.savefig(os.path.join(save_path,type+"_acc_loss.png")) if __name__ == '__main__': pass
作者:GISer_Lin



paddle googlenet

需要 登录 后方可回复, 如果你还没有账号请 注册新账号
相关文章
Thalia 2021-03-01
909