使用Flux构建二分类神经网络的输出维度问题咨询
解决Flux二分类模型输出维度问题
首先明确Flux的张量维度规则:特征在前,样本在后,即输入数据的形状应为(特征数, 样本数)。你的输入是100个3维特征的样本,正确的输入形状应该是3×100,而非100×3——这是导致你输出维度异常的核心原因。
下面给出两种符合预期的二分类模型实现方案:
方案一:单神经元输出(推荐,二分类常规做法)
这种方案输出每个样本属于正类的概率(范围0-1),负类概率可通过1 - 概率直接推导,无需额外输出第二维。
修正后代码
using Flux # 构造正确维度的输入:3个特征,100个样本 X = rand(3, 100) # 标签:100个样本的二分类标签(0/1),形状1×100 Y = rand([0,1], 1, 100) # 模型:输入特征数匹配X的第一维度3,最后一层输出1个神经元对应正类概率 model = Chain( Dense(3, 32, relu), Dense(32, 1), sigmoid ) # 损失函数与优化器 loss(x, y) = Flux.binarycrossentropy(model(x), y) opt = Flux.ADAM() # 训练 Flux.train!(loss, Flux.params(model), [(X, Y)], opt) # 验证输出:1×100的数组,对应每个样本的正类概率 println(size(model(X))) # 输出 (1, 100)
方案二:双神经元输出(输出两类概率)
如果需要明确输出每个样本的两类概率(形状2×100),可采用双神经元+softmax激活,同时标签需转为独热编码格式。
修正后代码
using Flux # 构造正确维度的输入 X = rand(3, 100) # 原始标签:100个样本的0/1标签 Y_raw = rand([0,1], 100) # 转为独热编码:形状2×100,每列对应一个样本的两类标签 Y = Flux.onehotbatch(Y_raw, [0, 1]) # 模型:最后一层输出2个神经元,对应两类概率 model = Chain( Dense(3, 32, relu), Dense(32, 2), softmax # 将输出归一化到概率和为1 ) # 损失函数用多分类交叉熵,适配独热标签 loss(x, y) = Flux.crossentropy(model(x), y) opt = Flux.ADAM() # 训练 Flux.train!(loss, Flux.params(model), [(X, Y)], opt) # 验证输出:2×100的矩阵,每列是对应样本的两类概率 println(size(model(X))) # 输出 (2, 100)
关键说明
- 你之前的模型输入层用
Dense(100, 32),会把输入的第一维度当成特征数(即认为每个样本有100个特征),而你的输入是100×3,相当于3个样本、每个样本100个特征,所以最终输出会是3个元素,这和你的实际需求完全不符。 - 无论哪种方案,核心是输入维度必须和模型第一层的输入特征数匹配,同时标签形状要和模型输出形状严格对应。
内容的提问来源于stack exchange,提问作者bSwizzle
相关产品推荐
相关产品推荐

