keras学习

机器学习中的凸函数和高数里的凹凸性不同。高数里是指曲线的凹凸性,机器学习里的凸函数和国外说的凹凸性是一致的,国内经济数学里的凹凸性也和国外说的一样,详情可看《数学分析》中凹凸性讲解。

断点训练方法:

在compile之后加入ModelCheckpoint:

cnn_net.compile(loss='categorical_crossentropy',optimizer='adam', metrics=['acc'])
path="C:/Users/Administrator/Desktop/pytest/weights.{epoch:02d}-{val_loss:.2f}.hdf5"
checkpoint = ModelCheckpoint(path,
    monitor='loss', save_weights_only=True,verbose=1,save_best_only=True, period=1)

其中命名为 weights.{epoch:02d}-{val_loss:.2f}.hdf5,模型被保存的的文件名就会有训练轮数和验证损失。

fit之前载入hdf5文件,就可以继续训练。

if os.path.exists("C:/Users/Administrator/Desktop/pytest/weights.05-0.03.hdf5"):
    cnn_net.load_weights("C:/Users/Administrator/Desktop/pytest/weights.05-0.03.hdf5")   
    print("checkpoint_loaded")
#训练模型
#validation_split:0~1之间的浮点数,用来指定训练集的一定比例数据作为验证集。验证集将不参与训练,并在每个epoch结束后测试的模型的指标,如损失函数、精确度等
hist=cnn_net.fit(x_train,y_train,batch_size=batch_size,epochs=15,verbose=1,validation_split=0.2,callbacks=[checkpoint],initial_epoch=5)#50

其中callbacks=[checkpoint]用来执行回调,initial_epoch=5设置起点轮数,设为5就会从第6轮开始。

Loss不下降问题:

1.比如出现:

 

很有可能是学习率lr或者batch_size的原因,减小学习率或者调整batch_size可以消除这种情况。减小学习率后,如图:

感觉第二轮的学习率减的有点多,还需要调整。

2、loss基本不变或者改变很小,如果改变学习率或者batch_size都没有好转,那很有可能是网络结构本身的问题。更改结构后,训练状况好转,如图:

使用预训练网络:

加载VGG的参数后,要进行特征提取,代码如下:

conv_base=VGG16(weights='imagenet',include_top=False,input_shape=(150,150,3))

datagen=ImageDataGenerator(1./255)
batch_size=32

def extract_feature(directory,sample_count):
    features=np.zeros(shape=(sample_count,4,4,512))
    labels=np.zeros(shape=(sample_count))
    generator=datagen.flow_from_directory(directory,target_size=(150,150),batch_size=batch_size,class_mode='binary')
    i=0
    for inputs_batch,labels_batch in generator:
        features_batch=conv_base.predict(inputs_batch)
        features[i*batch_size:(i+1)*batch_size]=features_batch
        labels[i*batch_size:(i+1)*batch_size]=labels_batch
        i+=1
        if i*batch_size>=sample_count:
            break
    return features,labels


train_feature,train_labels=extract_feature(train_dir,1420)
np.save(open('train_feature.npy','wb+'),train_feature)
np.save(open('train_labels.npy','wb+'),train_labels)
print('train save!')
test_feature,test_labels=extract_feature(test_dir,700)
np.save(open('test_feature.npy','wb+'),test_feature)
np.save(open('test_labels.npy','wb+'),test_labels)
print('test save!')

如果数据集比较小,可以直接读取,但是数据量比较大的时候,就应该读取之后保存,以便以后训练。用open保存一定要是“wb+”,否则会报错。制作数据集也可以用TensorFlow里的tfrecord进行制作,这个之后又时间再弄。读取保存的文件,也要是“rb”,具体如下:

train_feature=np.load(open('train_feature.npy','rb'))
train_labels=np.load(open('train_labels.npy','rb'))
test_feature=np.load(open('test_feature.npy','rb'))
test_labels=np.load(open('test_labels.npy','rb'))

参考:'gbk' codec can't decode bytekeras面向小数据集的图像分类

进行预测:

进行预测前,首先要对图片进行处理(resize和reshape),predict得到是概率,predict_classes得到的是分类结果。

test_model=load_model("net.h5")
src=cv2.imread("C:/Users/Administrator/Desktop/all/train/redata/dog.258.jpg")
src=cv2.resize(src,(150,150))#
src=src.reshape((1,150,150,3))
src=src.astype("float32")
src=src/255.0
re=test_model.predict(src)
print(re)
q=test_model.predict_classes(src)
print(q)

这种预测方式是对应普通训练的,如果用了预训练的方式要按下述方式进行预测:

src=cv2.imread("C:/Users/Administrator/Desktop/all/train/redata/dog.2547.jpg")
src=cv2.resize(src,(150,150))
x = image.img_to_array(src)
x = np.expand_dims(x, axis=0)
x = preprocess_input(x)
feature=conv_base.predict(x)
feature=feature.reshape(1,8192)
test_model=load_model("vgg.h5")
label=test_model.predict_classes(feature)
print(label)
re=test_model.predict(feature)
print(re)

经过试验,发现我使用的预训练读取文件的方式比网上(keras用vgg16预训练的参数训练自己数据集)的那些要好很多,读取一个batch,存一个batch,可以减缓电脑负担。

将预测结果保存为CSV文件:

目前使用方法:

print("test predict------")
#result = cnn_net.predict(x_test,batch_size=64,verbose=0)
result = cnn_net.predict_classes(x_test)
name=['test']
title=list(range(4000,7549))
result=pd.DataFrame(data=result,columns=name)
result.index=title
#result_test=pd.DataFrame(columns=name,data=result)
result.to_csv('result_4.csv',index=True)

title=list(range(4000,7549))    result.index=title是修改索引的值。主要参考:python 怎样把一个数组类型数据保存为csv文件—— 第六章 pandas入门,改变series和DataFrame索引 ——python写入csv文件的几种方法总结——pandas.DataFrame.to_csv——pandas.DataFrame

读取CSV文件:

在读取CSV文件时,使用 df=pd.read_csv("ck.csv") 读取文件,该函数会默认把文件的第一行做为标题,只读取后面的行,例如一个3*2的CSV文件,该函数读取出来的是2*2的。使用 df=pd.read_csv("ck.csv",header=None) 后,就可以全部读取,即读取的3*2的文件。参考:【解决方法】

Keras实现VGG:

def VGG_16(weights_path=None):
    model = Sequential()
    model.add(ZeroPadding2D((1,1),input_shape=(3,224,224)))#卷积输入层,指定了输入图像的大小
    model.add(Convolution2D(64, 3, 3, activation='relu'))#64个3x3的卷积核,生成64*224*224的图像,激活函数为relu
    model.add(ZeroPadding2D((1,1)))#补0,保证图像卷积后图像大小不变,其实用padding = 'valid'参数就可以了
    model.add(Convolution2D(64, 3, 3, activation='relu'))#再来一次卷积 生成64*224*224
    model.add(MaxPooling2D((2,2), strides=(2,2)))#pooling操作,相当于变成64*112*112
 
    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(128, 3, 3, activation='relu'))
    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(128, 3, 3, activation='relu'))
    model.add(MaxPooling2D((2,2), strides=(2,2)))#128*56*56
 
    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(256, 3, 3, activation='relu'))
    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(256, 3, 3, activation='relu'))
    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(256, 3, 3, activation='relu'))
    model.add(MaxPooling2D((2,2), strides=(2,2)))#256*28*28
 
    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(512, 3, 3, activation='relu'))
    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(512, 3, 3, activation='relu'))
    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(512, 3, 3, activation='relu'))
    model.add(MaxPooling2D((2,2), strides=(2,2)))#512*14*14
 
    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(512, 3, 3, activation='relu'))
    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(512, 3, 3, activation='relu'))
    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(512, 3, 3, activation='relu'))
    model.add(MaxPooling2D((2,2), strides=(2,2)))  #到这里已经变成了512*7*7
 
    model.add(Flatten())#压平上述向量,变成一维25088
    model.add(Dense(4096, activation='relu'))#全连接层有4096个神经核,参数个数就是4096*25088
    model.add(Dropout(0.5))#0.5的概率抛弃一些连接
    model.add(Dense(4096, activation='relu'))#再来一个全连接
    model.add(Dropout(0.5))
    model.add(Dense(1000, activation='softmax'))
 
    if weights_path:
        model.load_weights(weights_path)
 
    return model

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值