模型构造 讨论区

应该就是第一个dense的输出,进行固定参数的变换之后,再作为输入进入原来的那个dense内吧,这样就是复用一层dense,更新的是同一套参数,等价于两个dense共享一套参数

1赞

嗯嗯 虽然还有一些小问题 但是 很感谢您的热心解答!

兄弟,你找到答案了吗?同一层调用了两次, 反向传播的时候,以哪一次的梯度来更新参数呢?

我在照着沐神的视频敲batch_normalization的时候遇到了一点问题

def batch_norm(data, mode, moving_mean, moving_variance, gamma, beta):
if len(data.shape) == 4:
    mean = nd.mean(data, axis=(0, 2, 3), keepdims=True)
    variance = nd.mean((data-mean)**2, axis=(0, 2, 3), keepdims=True)
else:
    mean = nd.mean(data, axis=0, keepdims=True)
    variance = nd.mean((data - mean) ** 2, axis=0, keepdims=True)
if mode == "train":
    data_m = (data - mean) / nd.sqrt(variance + 1e-2)
    moving_mean[:] = 0.9 * moving_mean + 0.1 * mean
    moving_variance[:] = 0.9 * moving_variance + 0.1 * variance
else:
    data_m = (data - moving_mean) / nd.sqrt(moving_variance + 1e-2)
return gamma * data_m + beta

moving_mean1 = nd.zeros(shape=(1, w1.shape[0], 1, 1), ctx=ctx)

他会报错:

Traceback里一直说我这一行:
moving_mean[:] = 0.9 * moving_mean + 0.1 * mean

错误是:
Check failed: AGInfo::IsNone(*output): Assigning to NDArrays that are already in a computational graph will cause undefined behavior when evaluating gradients.

这里我 moving_mean1 没给梯度 不知道是哪里错了 能帮忙看下吗 谢谢

其他的地方应该没错,因为如果我让test的时候也计算均值和方差的话,出来的结果是ok的
就是在train的时候保存 moving_mean 和moving_variance 的时候报错
能不能帮我看下 对于python的函数传值我也一直理不清 谢谢

建议你先看一下现在的新PDF吧,感觉这个照着视频敲的程序,逻辑上有问题,如果是预测模式,有必要去计算平均值、方差吗,直接根据传入的参数更新就行了,可能是视频比较旧了???还有就是你这个缩进要注意一点!!!

可能是版本的 问题吧,我现在输出的结果就是和你预想的一样。

我想问问, 4.1.1.的net(X)以及output[2],在做什么,输出的是什么,有什么意义吗?

请问重复使用Dense层有什么作用呢?我在输出结果里没有发现不同,但是debug时候会有不同,比如若是写了重复使用Dense,我在第一层后写一个print,会输出正常的2*20的矩阵。若是没有写重复使用Dense,那个print就会输出一个被relu处理过的矩阵,请问为什么会这样?

不知可否有這樣的網路架構就是說
我想架一個神經網路輸入維度為4輸出為23
然而這23個輸出值彼此也有線性關係存在
然後這23個輸出值加總為100
昨天兜了一個晚上主要思路是
第一層4個x通過後預測1個y出來
然後把4個x加上預測出來的y一起丟到第二層
以此類推架23層,輸出只輸出23個y
後來train的時候一直說我模型有bug

练习题的参考答案(个人想法):
【1】首先,我们按照练习题将继承那句话super……注释掉,会出现错误:调用MLP()时,如果不继承父类的__init__函数,则因为初始化没有继承父类初始化过程中的一些参数,而无法正常使用父类的函数,也就无法继续进行向前传播,进而无法训练网络。
【2】我认为不会出现问题,不使用asscalar函数时判断条件结果为0或者1,使用asscalar函数判断结果为True或者False,然而while和if这两种方式都能正确决断,所以我觉得不会出现问题。
【3】根据题目将代码修改后,会报错,因为修改后会变成list类型,而不是Block, 这样就不会被自动注册到 Block 类的 self._children 属性, 导致 initialize 时在 self._children 找不到神经元, 无法初始化参数. 知道原因后,修改代码如下,到网络改成下面的结构:(第一张图片是修改后的代码,第二张图片是修改后代码的网网络结构,第三张是原来网络结构)显然可以看出来后面两层没有改变,只有前三层在使用不同类进行构造网络。
image

–*---------------------------------------------------------------
image

—*---------------------------------------------------------------
image

2赞

对于重复用Dense层有不解之处:
1、这种网络的设计有什么意义?
2、如果做backward,梯度肯定是每一层都计算一次,那我们学习的过程的Dense层的参数是对着两个梯度分别进行了一次计算么?