【问题标题】:Keras Binary Conv2D error "ValueError: logits and labels must have the same shape ((None, 1) vs (None, 4500))"Keras Binary Conv2D 错误“ValueError:logits 和标签必须具有相同的形状 ((None, 1) vs (None, 4500))”
【发布时间】:2021-09-29 16:11:34
【问题描述】:

我正在使用 CNN 对 DNA 序列进行二元分类,但无论我如何重构我的数据/网络,我都无法让二维二元分类 CNN 工作。我可以对标签进行一次热编码,并使用具有二元分类损失函数的 2 个神经元、softmax、密集层,但准确率仅徘徊在 50% 左右,更不用说完全错误地结合使用激活和损失。

数据是 5000 个 DNA 序列(分成 4500 个序列/500 个验证),每个 1000 个核苷酸长,经过标记化和一个热编码为 4x1000 矩阵(A、T、C、G)。标签只是 0/1 来表示它们是否有特定的主题。

# Returns Pandas dataframe of names, sequences, and labels that I generated
totalSeqs = GenSeqs()

# Splitting data and labels in to train/validation sets
x_tr, x_val, y_tr, y_val = train_test_split(totalSeqs.Sequences.tolist(), totalSeqs.Labels.tolist(), test_size = 0.1)
x_tr, x_val, y_tr, y_val = np.array(x_tr), np.array(x_val), np.array(y_tr), np.array(y_val)

#Tokenizing sequences
tk = Tokenizer(num_words=None, char_level=True)
tk.fit_on_texts(x_tr)
tokenTrain = tk.texts_to_sequences(x_tr)

# One hot encoding tokenized sequences
oneHotTrain = OneHot(tokenTrain)

# Resizing to fit Conv2D and making sure there aren't any array/list conflicts
# Saw someone else had this issue, so I went overboard on preventing it
oneHotTrain = np.array(oneHotTrain).reshape(-1, 4500, 1000, 4)
for x in oneHotTrain:
    x = np.array(x)
    for i in x:
        i = np.array(i)
        for j in i:
            j = np.array(j)
print(oneHotTrain.shape)

trainLabels = np.array(y_tr).reshape(-1, 4500, 1)
for x in trainLabels:
    x = np.array(x)
    for i in x:
        i = np.array(i)
        for j in i:
            j = np.array(j)
print(trainLabels.shape)

这都会输出序列的形状 (1, 4500, 1000, 4) 和标签的形状 (1, 4500, 1)。据我了解,这些是正确的形状,但很难获得有关标签形状的准确信息。

从这里,我创建了 CNN:

model = Sequential()
model.add(Conv2D(32, 4, activation='relu', input_shape = (4500, 1000, 4)))
model.add(MaxPooling2D(2))
model.add(Conv2D(64, 3, activation='relu'))
model.add(MaxPooling2D(2))
model.add(Flatten())
model.add(Dense(64, activation='relu'))
model.add(Dense(1, activation='sigmoid'))

model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

model.summary()
          
final = model.fit(oneHotTrain, trainLabels, batch_size = 100, epochs = 3, verbose = 1)

作为参考,这是我使用的一个热编码功能:

def OneHot(data):
    num_classes = 4
    new_data = []

    for x in data:
        class_vector = np.array(x)
        categorical = np.zeros(class_vector.shape+(num_classes,))
        for c in range(1,5,1):
            categorical[np.where(class_vector == c)]=np.array([1 if i == c else 0.0 for i in range(1,5,1)])
        new_data.append(categorical)
        
    return new_data

它的输出结果很好,我用来生成“DNA”的函数只创建了 1000 个字符长且仅由 A/T/C/G 组成的序列。我已经通过从 Tokenizer 输出信息、它们的长度等验证了所有这些,无论哪种方式,最后一个热矩阵结果都很好,所以我认为问题不存在,甚至不存在于一个热函数本身.

我的假设是错误存在于 CNN 架构/参数或数据/标签形状的某个地方,但如果我可能遗漏了什么。有什么建议吗?

【问题讨论】:

  • (1, 4500, 1) 不是正确的形状,样本维度是第一个,然后是类的#,无论如何这是正确的。
  • 准确地说 (4500, 1) 对您的标签来说是正确的。
  • @Dr.Snoopy 好的,但是每当我将标签形状更改为 (4500, 1) 时,我都会收到错误消息:“ValueError:数据基数不明确:x 大小:1 y 大小:4500 请提供共享相同第一维度的数据。”
  • 你还需要确保训练数据的格式正确,它可能有同样的问题。
  • 如果我在训练数据的开头去掉1维,我得到错误:“ValueError: Input 0 of layer sequence_1 is in compatible with the layer: : expected min_ndim=4, found ndim=3。收到的完整形状:[100, 1000, 4]"。

标签: python numpy tensorflow keras conv-neural-network


【解决方案1】:

我发现了问题,结果变成了一串问题……

  1. 第一个 Conv2D 层的input_size 需要 3 个维度,前 2 个是长度/宽度,最后一个是深度。因为我处理的是单个文本序列,所以我的输入是(1000, 4, 1)。如果您正在处理彩色图像,那么我假设您的最终值为 3,以考虑颜色通道。
  2. 设置完成后,我收到有关 Conv2D 层的预期 ndim 和负尺寸的错误。首先,我将我的数据重新调整为 (4500, 1000, 4, 1),这很有效,我认为它应该反映数据的每个级别的细分,但还没有完全清楚地了解这一点。
  3. 最后,负维度的问题来自 Conv2D 和 MaxPooling2D 层中的内核大小。由于我将它们分别设置为 4 和 2,这意味着它们是 (4,4)(2,2),它们试图将 4 和 2 平方尺寸应用于序列的各个 4x1 部分(因为它们是一个热编码的)。为了解决这个问题,我只是将第一个 Conv2D 和 MaxPooling2D 层更改为 (4,1)(2,1)

完成所有这些之后,它运行良好,我终于得到了很好的结果。这只是我创建的一个玩具示例,用于理解为什么我的研究 CNN 不起作用,所以一旦我能够弄清楚这一点,我就让研究 CNN 抽出结果。感觉不错。

【讨论】:

    猜你喜欢
    • 2021-08-08
    • 2021-03-23
    • 2020-09-30
    • 2021-07-27
    • 2021-10-28
    • 2021-07-28
    • 1970-01-01
    • 1970-01-01
    • 2021-04-08
    相关资源
    最近更新 更多