from __future__ import print_function
import numpy as np
from keras.callbacks import EarlyStopping
from keras.layers.core import Dense, Activation
from keras.models import Sequential
from keras.optimizers import SGD
from keras.layers import Layer
import keras.backend as K
np.random.seed(1337) # for reproducibility
class Round(Layer):
def __init__(self, **kwargs):
super(Round, self).__init__(**kwargs)
def get_output(self, train=False):
X = self.get_input(train)
return K.round(X)
def get_config(self):
config = {"name": self.__class__.__name__}
base_config = super(Round, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
def build_and_train_mlp_network(X_train, y_train, X_test, y_test):
nb_epoch = 1000
batch_size = 4
model = Sequential()
model.add(Dense(2, input_shape=(X_train.shape[1],)))
model.add(Activation('sigmoid'))
model.add(Dense(1))
model.add(Activation('sigmoid'))
model.add(Round()) # return K.round(X)
sgd = SGD(lr=0.1, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='mean_squared_error', optimizer=sgd) # or binary_crossentropy
model.fit(X_train,
y_train,
batch_size=batch_size,
nb_epoch=nb_epoch,
verbose=0,
validation_data=(X_test, y_test))
return model
if __name__ == "__main__":
X_test = X_train = np.array([[1, 1], [1, 0], [0, 1], [0, 0]])
y_train = y_test = np.array([1, 2, 3, 4])
model = build_and_train_mlp_network(X_train, y_train, X_test, y_test)
print(model.predict(X_test))
如何将此模型输出从float更改为string?
输出为[[0.9999342 ] [0.99991477] [0.99989116] [0.9998405 ]]
现在我改变
y_train = y_test = np.array(['a', 'b', 'c', 'd'])
如何使输出(model.predict(X_test))成为字符串?
答案 0 :(得分:1)
这里涉及一些猜测:我假设您的“舍入”层目的是获得一个整数的输出。但是,这样一来,您很有可能会破坏SGD中的梯度。
为避免梯度问题,您应该在后期处理步骤中进行操作。因此,我建议通过以下方式更改神经网络:
model = Sequential()
model.add(Dense(2, input_shape=(X_train.shape[1],)))
model.add(Activation('sigmoid'))
model.add(Dense(1))
# model.add(Activation('sigmoid'))
model.add(Activation('linear'))
线性激活以获得大于1
的数字。此功能是您获得[[0.9999342 ] [0.99991477] [0.99989116] [0.9998405 ]]
的原因
之后,您可以对输出进行后期处理
print(np.round(model.predict(X_test)))
或映射到可以使用的字符
maps = ['foo','a','b','c','d','bar'] # ugly what about -1...6,... etc
[maps[int(round(i))] for i in model.predict(X_test).flatten()]
使用功能性API,您实际上可以将舍入推入NN。我不得不重新编写您的图层
class Round(Layer):
def __init__(self, **kwargs):
super(Round, self).__init__(**kwargs)
def call(self,X):
print(X)
return K.round(X)
def get_config(self):
config = {"name": self.__class__.__name__}
base_config = super(Round, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
r = Round()(outputs)
sgd = SGD(lr=0.1, decay=1e-6, momentum=0.9, nesterov=True)
modelr = Model(inputs=inputs, outputs=r)
modelr.compile(loss='mean_squared_error', optimizer=sgd)
modelr.predict(X_test)
说过,我认为您的模型存在根本缺陷。该模型假定字符中存在顺序。这意味着b
在a
和c
之间。从字母的角度来看,这是正确的,但是在语义上是错误的。
因此,您应该使用标准的一键编码方法。同样不会发生使foo
,bar
等不可拼写的字符出现的问题。查看标准TF / Keras Mnist示例
然后您可以通过以下方式构建模型
from keras.utils import np_utils
num_classes=5 # sorry but we need zero
def build_and_train_mlp_network(X_train, y_train, X_test, y_test):
nb_epoch = 1000
batch_size = 4
inputs = Input(shape=(X_train.shape[1],))
d1 = Dense(2)(inputs)
a1 = Activation('sigmoid')(d1)
d2 = Dense(num_classes)(a1)
a2 = Activation(activation='softmax')(d2)
model = Model(inputs=inputs, outputs=a2)
sgd = SGD(lr=0.1, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='mean_squared_error', optimizer=sgd) # or binary_crossentropy
model.fit(X_train,
y_train,
batch_size=batch_size,
nb_epoch=nb_epoch,
verbose=0,
validation_data=(X_test, y_test))
return model,inputs,a2
X_test = X_train = np.array([[1, 1], [1, 0], [0, 1], [0, 0],[1, 1]])
y_train = y_test = np_utils.to_categorical(np.array([0, 1, 2, 3,0]),num_classes=5)
model,inputs,outputs = build_and_train_mlp_network(X_train, y_train, X_test, y_test)
print(model.summary())
model.predict(X_test)
,如果您想再次从计算图获取max class
class ArgMax(Layer):
def __init__(self, **kwargs):
super(ArgMax, self).__init__(**kwargs)
def call(self,X):
print(X)
return K.argmax(X, axis=None)
def get_config(self):
config = {"name": self.__class__.__name__}
base_config = super(Round, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
am = ArgMax()(outputs)
modelam=Model(inputs=inputs,outputs=[am,outputs])
clazzes,confidence = modelam.predict(X_test)