我试图了解自动编码器中的功能有多深。
我用h2o.deeplearning
创建了一个自动编码器然后我尝试了
手动计算深度特征。
fit = h2o.deeplearning(
x = names(x_train),
training_frame = x_train,
activation = "Tanh",
autoencoder = TRUE,
hidden = c(25,10),
epochs = 100,
export_weights_and_biases = TRUE,
)
我用作激活函数Tanh和2个没有丢失的隐藏层,到 让事情变得简单。
然后我提取了从输入层到隐藏层1的重量和偏差
w12 = as.matrix(h2o.weights(fit, 1))
b12 = as.matrix(h2o.biases (fit,1))
我为这些操作准备了训练数据 紧凑区间[-0.5,0.5],因为h2o自动执行此操作 自动编码
normalize = function(x) {(((x-min(x))/(max(x)-min(x))) - 0.5)}
d.norm = apply(d, 2, normalize)`
然后我手动计算了第一层的深度特征
a12 = d.norm %*% t(w12)
b12.rep = do.call(rbind, rep(list(t(b12)), nrow(d.norm)))
z12 = a12 + b12.rep
f12 = tanh(z12)
当我将这些值与隐藏的第1层深层特征进行比较时,它们不匹配
hl1.output = as.matrix(h2o.deepfeatures(fit, x_train, layer = 1))
all.equal(
as.numeric(f12[,1]),
hl1.output[, 1],
check.attributes = FALSE,
use.names = FALSE,
tolerance = 1e-04
)
[1] "Mean relative difference: 0.4854887"
然后我尝试做同样的事情来手动计算其深层特征 hiddem层2来自隐藏层1的深层特征
a23 = hl1.output %*% t(w23)
b23.rep = do.call(rbind, rep(list(t(b23)), nrow(a23)))
z23 = a23 + b23.rep
f23 = tanh(z23)
将这些值与隐藏层2的深层特征进行比较 我看到他们匹配完美
hl2.output = as.matrix(h2o.deepfeatures(fit,x_train,layer = 2))
all.equal(
as.numeric(f23[,1]),
hl2.output[, 1],
check.attributes = FALSE,
use.names = FALSE,
tolerance = 1e-04
)
[1] TRUE
我为输出层尝试了同样的事情
a34 = hl2.output %*% t(w34)
b34.rep = do.call(rbind, rep(list(t(b34)), nrow(a34)))
z34 = a34 + b34.rep
f34 = tanh(z34)
我将结果与我的输出进行了比较,但我得不到相同的结果
all.equal(
as.numeric(f34[1,]),
output[1,],
check.attributes = FALSE,
use.names = FALSE,
tolerance = 1e-04
)
[1] "Mean relative difference: 3.019762"
我认为我没有以正确的方式对数据进行规范化,因为我可以使用隐藏层1的功能重新创建隐藏层2的深层特征。我不明白错误,因为{{1} } h2o应规范化[-0.5:0.5]
之间的数据我不明白为什么输出层的手动计算没有 工作
1)如何手动计算隐藏层1的深层特征?
2)如何手动计算输出功能?
答案 0 :(得分:1)
您正在使用:
normalize = function(x) {(((x-min(x))/(max(x)-min(x))) - 0.5)}
他们正在使用this Java code:
normMul[idx] = (v.max() - v.min() > 0)?1.0/(v.max() - v.min()):1.0;
normSub[idx] = v.mean();
然后使用like this:
numVals[i] = (numVals[i] - normSub[i])*normMul[i];
即。减去均值,然后除以范围(或等效地,在该范围内乘以1)。因此,忽略对零除的检查,我认为您的R代码必须是:
normalize = function(x) {(x-mean(x))/(max(x)-min(x))}
检查为零,如:
normalize = function(x) {mul=max(x)-min(x);if(mul==0)mul=1;return((x-mean(x))/mul)}
只是玩弄它,似乎有1.0的范围,但它不以0.0为中心,即它不是H2O文档中描述的-0.5到+0.5(例如深度学习小册子中的第20页)。我是否遗漏了Java代码中的内容?
顺便说一下,this line决定为自动编码器设定NORMALIZE,而不是STANDARDIZE用于其他深度学习。