我使用Wild ML实现的CNN模型进行了训练,该模型可以在这里找到,并已将其部署到Google Cloud Platform。现在我尝试向模型发送JSON预测请求,但遇到了以下错误:
Traceback (most recent call last): File "C:/Users/XXX/PycharmProjects/CNN-Prediction/prediction.py", line 73, in <module> print(predict_json(project, model, [json_request], version="TestV2")) File "C:/Users/XXX/PycharmProjects/CNN-Prediction/prediction.py", line 63, in predict_json raise RuntimeError(response['error'])RuntimeError: Prediction failed: Error during model execution: AbortionError(code=StatusCode.INVALID_ARGUMENT, details="Shape [-1,11] has negative dimensions [[Node: input_y = Placeholder[_output_shapes=[[-1,11]], dtype=DT_FLOAT, shape=[?,11], _device="/job:localhost/replica:0/task:0/cpu:0"]()]]")
我发现理解这个错误有一定的挑战,但我认为这可能是因为我向模型发送了JSON数据,而模型需要接受一个整数数组,这一点可以在下面的TextCNN类中看到。
问题:在代码的哪个位置以及如何实现修改,以便将JSON输入请求转换为模型可以操作的格式?
class TextCNN(object):"""用于文本分类的CNN。使用嵌入层,后跟卷积、最大池化和softmax层。"""# 构造函数 - sequence length = 投诉中的gram数量, num_classes = 类别数量, vocab_size, embedding_size = 嵌入的维度def __init__( self, sequence_length, num_classes, vocab_size, embedding_size, filter_sizes, num_filters, l2_reg_lambda=0.0): # 输入、输出和dropout的占位符 self.input_x = tf.placeholder(tf.int32, [None, sequence_length], name="input_x") # 神经网络接口用于接受投诉 self.input_y = tf.placeholder(tf.float32, [None, num_classes], name="input_y") # 神经网络接口用于接受投诉标签 self.dropout_keep_prob = tf.placeholder(tf.float32, name="dropout_keep_prob") # 跟踪l2正则化损失(可选) l2_loss = tf.constant(0.0) # 嵌入层 - 将词汇表中的词索引映射到低维向量表示(基本上是查找表) # name_scope - 将所有操作添加到顶级节点'embedding'中 - 在TensorBoard中可视化时有很好的层次结构 # 嵌入层 with tf.device('/cpu:0'), tf.name_scope("embedding"): self.W = tf.Variable( tf.random_uniform([vocab_size, embedding_size], -1.0, 1.0), trainable=False, name="W") self.embedded_chars = tf.nn.embedding_lookup(self.W, self.input_x) # 使用权重矩阵将投诉中的词索引映射 self.embedded_chars_expanded = tf.expand_dims(self.embedded_chars, -1) # 扩展张量的维度,以便使用conv2d # 为每个滤波器大小创建一个卷积 + 最大池化层 # 由于我们有不同大小的滤波器,每个卷积产生不同形状的张量,因此我们需要迭代它们, pooled_outputs = [] for i, filter_size in enumerate(filter_sizes): with tf.name_scope("conv-maxpool-%s" % filter_size): # 卷积层 filter_shape = [filter_size, embedding_size, 1, num_filters] W = tf.Variable(tf.truncated_normal(filter_shape, stddev=0.1), name="W") b = tf.Variable(tf.constant(0.1, shape=[num_filters]), name="b") conv = tf.nn.conv2d( self.embedded_chars_expanded, W, strides=[1, 1, 1, 1], padding="VALID", name="conv") # 应用非线性 h = tf.nn.relu(tf.nn.bias_add(conv, b), name="relu") # 在输出上进行最大池化 pooled = tf.nn.max_pool( h, ksize=[1, sequence_length - filter_size + 1, 1, 1], strides=[1, 1, 1, 1], padding='VALID', name="pool") pooled_outputs.append(pooled) # 组合所有池化特征 num_filters_total = num_filters * len(filter_sizes) print(pooled_outputs) self.h_pool = tf.concat(pooled_outputs, axis=3) self.h_pool_flat = tf.reshape(self.h_pool, [-1, num_filters_total]) # 添加dropout with tf.name_scope("dropout"): self.h_drop = tf.nn.dropout(self.h_pool_flat, self.dropout_keep_prob) # 最终(未归一化)的分数和预测 with tf.name_scope("output"): W = tf.get_variable( "W", shape=[num_filters_total, num_classes], initializer=tf.contrib.layers.xavier_initializer()) b = tf.Variable(tf.constant(0.1, shape=[num_classes]), name="b") l2_loss += tf.nn.l2_loss(W) l2_loss += tf.nn.l2_loss(b) self.scores = tf.nn.xw_plus_b(self.h_drop, W, b, name="scores") self.predictions = tf.argmax(self.scores, 1, name="predictions") # 计算平均交叉熵损失 with tf.name_scope("loss"): print(self.scores) print(self.input_y) losses = tf.nn.softmax_cross_entropy_with_logits(logits=self.scores, labels=self.input_y) self.loss = tf.reduce_mean(losses) + l2_reg_lambda * l2_loss # 准确率 with tf.name_scope("accuracy"): correct_predictions = tf.equal(self.predictions, tf.argmax(self.input_y, 1)) self.accuracy = tf.reduce_mean(tf.cast(correct_predictions, "float"), name="accuracy")
回答:
这个问题与train.py
和text_cnn.py
无关。它们用于构建您的模型。在构建模型后,请在eval.py
代码中进行以下修改。
首先,您可以使用参数库来获取您的JSON文件。
import argparseparser = argparser.ArgumentParser()# 输入参数parser.add_argument( '--eval-file', help='本地评估数据路径', nargs='+', required=True )args = parser.parse_args()
然后您可以按以下方式执行您的代码:
python eval.py --eval-file 您的JSON文件
然后使用,
import jsonjson.loads(Data)
从args
中获取您的数据,或者使用字典库将您的数据转换为以下数组格式:
x_raw = ["key", "Value"] x_test = np.array(list(vocab_processor.transform(x_raw)))
将您的数据转换为x_raw
后,上述代码会将您的数据转换为TensorFlow适用的格式。