从TF1迁移到TF2后,如何获取非Keras模型的概率输出?
问题解答
你的当前模型是回归任务模型(使用均方误差MSE作为损失函数),输出是连续数值,本身没有概率输出的概念。但如果你的实际任务是分类任务(二分类/多分类),可以通过修改模型输出层和损失函数来实现概率输出,具体步骤如下:
一、明确任务类型与对应修改方案
1. 多分类任务(输出为每个类别的概率,总和为1)
- 修改输出层:添加
softmax激活函数,让输出值映射为0-1之间的概率,且所有类别概率和为1 - 替换损失函数:使用交叉熵损失(适配分类任务的损失计算)
2. 二分类任务(输出为样本属于正类的概率)
- 修改输出层:添加
sigmoid激活函数,输出值为0-1之间的单值概率 - 替换损失函数:使用二元交叉熵损失
二、具体代码修改示例
多分类任务修改版
tf.compat.v1.reset_default_graph() # 原代码此处缺少括号,需补上 X = tf.compat.v1.placeholder(tf.float32, [None, n_steps, n_inputs],name="input") y = tf.compat.v1.placeholder(tf.float32, [None, n_outputs],name="output") # y需为one-hot编码格式 layers = [tf.compat.v1.nn.rnn_cell.LSTMCell(num_units = n_neurons, activation = tf.nn.leaky_relu, use_peepholes = True, name = "layer"+str(layer)) for layer in range(n_layers) ] multi_layer_cell = tf.compat.v1.nn.rnn_cell.MultiRNNCell(layers) rnn_outputs, states = tf.compat.v1.nn.dynamic_rnn(multi_layer_cell, X, dtype=tf.float32) stacked_rnn_outputs = tf.reshape(rnn_outputs, [-1, n_neurons]) # 先计算未激活的logits(用于交叉熵损失,避免数值不稳定) stacked_logits = tf.compat.v1.layers.dense(stacked_rnn_outputs, n_outputs) # 添加softmax激活得到概率输出 stacked_probs = tf.nn.softmax(stacked_logits) outputs = tf.reshape(stacked_probs, [-1, n_steps, n_outputs]) outputs = tf.identity(outputs[:, n_steps-1, :], name="prediction") # 此处outputs即为概率值 # 替换损失函数为多分类交叉熵 loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(labels=y, logits=stacked_logits)) optimizer = tf.compat.v1.train.AdamOptimizer(learning_rate = learning_rate) training_op = optimizer.minimize(loss, name = "training_op")
二分类任务修改版
tf.compat.v1.reset_default_graph() X = tf.compat.v1.placeholder(tf.float32, [None, n_steps, n_inputs],name="input") y = tf.compat.v1.placeholder(tf.float32, [None, 1],name="output") # y为0/1的标签格式 layers = [tf.compat.v1.nn.rnn_cell.LSTMCell(num_units = n_neurons, activation = tf.nn.leaky_relu, use_peepholes = True, name = "layer"+str(layer)) for layer in range(n_layers) ] multi_layer_cell = tf.compat.v1.nn.rnn_cell.MultiRNNCell(layers) rnn_outputs, states = tf.compat.v1.nn.dynamic_rnn(multi_layer_cell, X, dtype=tf.float32) stacked_rnn_outputs = tf.reshape(rnn_outputs, [-1, n_neurons]) # 先计算未激活的logits stacked_logits = tf.compat.v1.layers.dense(stacked_rnn_outputs, 1) # 添加sigmoid激活得到概率输出 stacked_probs = tf.nn.sigmoid(stacked_logits) outputs = tf.reshape(stacked_probs, [-1, n_steps, 1]) outputs = tf.identity(outputs[:, n_steps-1, :], name="prediction") # 此处outputs即为正类概率 # 替换损失函数为二元交叉熵 loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(labels=y, logits=stacked_logits)) optimizer = tf.compat.v1.train.AdamOptimizer(learning_rate = learning_rate) training_op = optimizer.minimize(loss, name = "training_op")
三、补充说明
- 原代码中
tf.compat.v1.reset_default_graph缺少括号,需要修正为tf.compat.v1.reset_default_graph(),否则无法执行重置图的操作 - 分类任务中,标签
y的格式要对应:多分类需为one-hot编码,二分类需为0/1的单值标签 - 不需要依赖Keras的
predict_proba方法,在你的TF1兼容代码中,运行模型后得到的outputs张量值就是直接的概率输出
内容的提问来源于stack exchange,提问作者Jaffer Wilson
相关产品推荐
相关产品推荐

