wepe / MachineLearning

Basic Machine Learning and Deep Learning
5.07k stars 3.16k forks source link

DeepLearning Tutorials:keras_usage:并未找到保存的model.pkl,cnn.py文件中没有用于保存的代码啊? #4

Closed Imorton-zd closed 8 years ago

Imorton-zd commented 8 years ago

您好,看到您博文上利用keras训练CNN并保存训练好的CNN模型,并未找到保存的model.pkl,cnn.py文件中没有用于保存的代码啊? 还有,我用cnn做文本分类的,如果想要把每层的输出写到文件里面,留作他用,该怎么操作? 其实,跟您写的cnn_svm思想是一致的,提取特征之后再用其他的方法分类,但是不知道文本和图像得到输出的方法是不是一样 麻烦大神了!

wepe commented 8 years ago

dive_into_keras里面的cnn.py有保存model的代码:cnn.py#L94

cPickle.dump(model,open("./model.pkl","wb"))

获取每一层的输出,你可以参考这两行cnn-svm.py#L54#L55

get_feature = theano.function([origin_model.layers[0].input],origin_model.layers[11].get_output(train=False),allow_input_downcast=False)
feature = get_feature(data)

得到的feature的类型是numpy array(应该是吧~没验证过),numpy里有些内置的函数可以将array保存到文件里,像ndarray.tofile、numpy.savetxt,你可以搜一下这方面的用法。或者,如果你只是想把每层的输出保存下来,直接用cPickle序列化也是可以的。

Imorton-zd commented 8 years ago

@wepe 您好,按照您的方法保存模型会报错哎


model.compile(loss='binary_crossentropy', optimizer='rmsprop',class_mode="binary")

f1 = open('cnn_train_loss_acc.txt','w')
f2 = open('cnn_test_loss_acc.txt','w')
best_accuracy = 0.0
for e in range(nb_epoch):
    #shuffle the data each epoch
    np.random.seed(seed)
    np.random.shuffle(X_train)
    np.random.seed(seed)
    np.random.shuffle(Y_train)

    print('Epoch', e)
    print("Training...")
    batch_num = len(Y_train)/batch_size
    progbar = generic_utils.Progbar(X_train.shape[0])
    for i in range(batch_num):
        loss,accuracy = model.train_on_batch(X_train[i*batch_size:(i+1)*batch_size], Y_train[i*batch_size:(i+1)*batch_size],accuracy=True)
        progbar.add(batch_size, values=[("train loss", loss),("train accuracy:", accuracy)] )
        f1.write('batch%d:train loss:%s---train accuracy:%s\n'%(i,loss,accuracy))

    #save the model of best val-accuracy
    print("Validation...")
    val_loss,val_accuracy = model.evaluate(X_test, Y_test, batch_size=1,show_accuracy=True)
    f2.write('epoch%d:test loss:%s---test accuracy:%s\n'%(e,val_loss,val_accuracy))
    if best_accuracy<val_accuracy:
        best_accuracy = val_accuracy
    cPickle.dump(model,open(r"Model\model_cnn.pkl","wb"))

f1.close()
f2.close()

Traceback (most recent call last):
  File "D:\workspace\search\src\CNN\text_classification_test.py", line 258, in <module>
    cPickle.dump(model,open(r"Model\model_cnn.pkl","wb"))
  File "D:\Python27\lib\copy_reg.py", line 70, in _reduce_ex
    raise TypeError, "can't pickle %s objects" % base.__name__
TypeError: can't pickle function objects

请问这是什么问题啊? 而且好像这里面的 best_accuracy没有起到任何作用啊,既没有输出,也没有利用它来保存最优模型啊

wepe commented 8 years ago
if best_accuracy<val_accuracy:
        best_accuracy = val_accuracy
        cPickle.dump(model,open(r"Model\model_cnn.pkl","wb"))

cPickle.dump...这一行'缩进一下,我本意是在获得当前最佳val_accuracy的时候就保存模型,因为可能随着模型的训练,后面的epoch的val_accurary会减小。

Imorton-zd commented 8 years ago

@wepe 谢谢大神啊! 下面那行获得特征的语句,是从第11层获得特征吗?也就是每个add就是一层,11层指的是model.add(Dense(16_4_4, 128, init='normal')) model.add(Activation('relu'))之后的 输出吗?

get_feature = theano.function([origin_model.layers[0].input],origin_model.layers[11].get_output(train=False),allow_input_downcast=False)
def create_model():
    model = Sequential()
    model.add(Convolution2D(4, 1, 5, 5, border_mode='valid')) 
    model.add(Activation('relu'))

    model.add(Convolution2D(8,4, 3, 3, border_mode='valid'))
    model.add(Activation('relu'))
    model.add(MaxPooling2D(poolsize=(2, 2)))

    model.add(Convolution2D(16, 8, 3, 3, border_mode='valid')) 
    model.add(Activation('relu'))
    model.add(MaxPooling2D(poolsize=(2, 2)))

    model.add(Flatten())
    model.add(Dense(16*4*4, 128, init='normal'))
    model.add(Activation('relu'))
    model.add(Dropout(0.2))

    model.add(Dense(128, nb_class, init='normal'))
    model.add(Activation('softmax'))
    return model
wepe commented 8 years ago

@Imorton-zd 不客气啊~ model.add(layer) 这里add方法的参数就是一个layer,所以应该是的

Imorton-zd commented 8 years ago

@wepe 请问您有没有用过convolution1D啊,我用来做文本分类的。如果我想再加一层卷积,接下来应该怎么写啊,第二层卷积的输入多少? 因为文本方面的卷积网上讲的不多,我本身才接触深度学习,所以麻烦您啦!

model = Sequential()

# we start off with an efficient embedding layer which maps
# our vocab indices into embedding_dims dimensions
model.add(Embedding(max_features, embedding_dims))
model.add(Dropout(0.25))

# we add a Convolution1D, which will learn nb_filters
# word group filters of size filter_length:
model.add(Convolution1D(input_dim=embedding_dims,
                        nb_filter=nb_filters,
                        filter_length=filter_length,
                        border_mode="valid",
                        activation="relu",
                        subsample_length=1))

# we use standard max pooling (halving the output of the previous layer):
model.add(MaxPooling1D(pool_length=2))

# We flatten the output of the conv layer, so that we can add a vanilla dense layer:
model.add(Flatten())

# Computing the output shape of a conv layer can be tricky;
# for a good tutorial, see: http://cs231n.github.io/convolutional-networks/
output_size = nb_filters * (((maxlen - filter_length) / 1) + 1) / 2

# We add a vanilla hidden layer:
model.add(Dense(output_size, hidden_dims))
model.add(Dropout(0.25))
model.add(Activation('relu'))

model.add(Dense(hidden_dims, nb_classes))
model.add(Activation('softmax'))

还有为什么代码中output_size那样算啊?

alyato commented 8 years ago

我训练好了一个模型,按照代码保存为pkl格式。但是,我怎么知道模型里的具体参数,例如训练的准确率,和验证的准确率?

alyato commented 8 years ago

xx 我运行的时候并没有出现这种情况,能够看到保存的pkl模型 。但是代码不一样。