一,前言
有这么个需求,输入一张图,返回多个特征。比如输入一个数字,返回他的数字意义和字符颜色。这两个特征可以使用不同的训练参数。
二 ,代码部分
代码。线性。适合获取操作值, 比如弄个赛车游戏,给一张图像训练他的油门值和左右值。
import tensorflow as tf
import numpy as np
import scipy as sp
mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0
class multipleOutputNet(object):
@staticmethod
def netOne(input, numCategories, finalAct = "softmax", chanDim=-1):
h1 = tf.keras.layers.Conv2D(16, 3, padding="same", activation='relu')(input)
h1 = tf.keras.layers.MaxPool2D(3)(h1)
h1 = tf.keras.layers.Conv2D(32, 3, activation='relu')(h1)
h1 = tf.keras.layers.MaxPool2D(3)(h1)
h1 = tf.keras.layers.Dense(256, activation='relu')(h1)
h1 = tf.keras.layers.Dropout(0.2)(h1)(h1)
h1 = tf.keras.layers.Dense(1, activation='tanh')(h1)
return h1
@staticmethod
def netTwo(input, numCategories, finalAct="softmax", chanDim=-1):
h1 = tf.keras.layers.Flatten()(input)
h1 = tf.keras.layers.Dense(256, activation='relu')(h1)
h1 = tf.keras.layers.Dropout(0.2)(h1)
h1 = tf.keras.layers.Dense(1, activation='tanh')(h1)
return h1
@staticmethod
def buildNet(width, height, chanal, netOneCount, netTwoCount, finalAct = "softmax"):
inputShape = (height, width, chanal)
chanDim = -1
input = tf.keras.Input(shape=inputShape)
netOneBranch = multipleOutputNet.netOne(input, netOneCount, finalAct=finalAct, chanDim=chanDim)
netTwoBranch = multipleOutputNet.netTwo(input, netTwoCount, finalAct=finalAct, chanDim=chanDim)
model = tf.keras.Model(input, [netOneBranch, netTwoBranch])
return model
model = multipleOutputNet.buildNet(28, 28, 1, netOneCount=1, netTwoCount=1, finalAct="softmax")
losses = (
'sparse_categorical_crossentropy',
'sparse_categorical_crossentropy'
)
losses1 = (
'mean_squared_error',
'mean_squared_error'
)
lossWeights = (0.1, 0.1)
model.compile(optimizer=tf.keras.optimizers.SGD(lr=0.01),
loss=losses1,
metrics=['accuracy']
)
x_train = np.reshape(x_train, (60000, 28, 28, 1))
y_train_r = y_train * 0.1
y_train_r1 = y_train * 0.01
model.fit(x_train, (y_train_r, y_train_r1), epochs=50)
model.save('t1.h5')
代码 。非线性。 即适合多分类的。比如给一个水果图像,获取他的品种和颜色
import tensorflow as tf
import numpy as np
import scipy as sp
mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0
class multipleOutputNet(object):
@staticmethod
def netOne(input, numCategories, finalAct = "softmax", chanDim=-1):
h1 = tf.keras.layers.Conv2D(16, 3, padding="same", activation='relu')(input)
h1 = tf.keras.layers.MaxPool2D(3)(h1)
h1 = tf.keras.layers.Conv2D(32, 3, activation='relu')(h1)
h1 = tf.keras.layers.MaxPool2D(3)(h1)
h1 = tf.keras.layers.Conv2D(32, 3, activation='relu')(h1)
h1 = tf.keras.layers.Flatten()(h1)
h1 = tf.keras.layers.Dense(256, activation='relu')(h1)
h1 = tf.keras.layers.Dropout(0.2)(h1)
h1 = tf.keras.layers.Dense(10, activation='softmax')(h1)
return h1
@staticmethod
def netTwo(input, numCategories, finalAct="softmax", chanDim=-1):
h1 = tf.keras.layers.Flatten()(input)
h1 = tf.keras.layers.Dense(256, activation='relu')(h1)
h1 = tf.keras.layers.Dropout(0.2)(h1)
h1 = tf.keras.layers.Dense(10, activation='softmax')(h1)
return h1
@staticmethod
def buildNet(width, height, chanal, netOneCount, netTwoCount, finalAct = "softmax"):
inputShape = (height, width, chanal)
chanDim = -1
input = tf.keras.Input(shape=inputShape)
netOneBranch = multipleOutputNet.netOne(input, netOneCount, finalAct=finalAct, chanDim=chanDim)
netTwoBranch = multipleOutputNet.netTwo(input, netTwoCount, finalAct=finalAct, chanDim=chanDim)
model = tf.keras.Model(input, [netOneBranch, netTwoBranch])
return model
model = multipleOutputNet.buildNet(28, 28, 1, netOneCount=10, netTwoCount=10, finalAct="softmax")
losses = (
'sparse_categorical_crossentropy',
'sparse_categorical_crossentropy'
)
lossWeights = (0.1, 0.1)
model.compile(optimizer='adam',
loss=losses,
metrics=['accuracy']
)
x_train = np.reshape(x_train, (60000, 28, 28, 1))
y_train_r = y_train * 0.1
model.fit(x_train, (y_train, y_train_r), epochs=50)
model.save('t1.h5')