模型构造 讨论区


#44

:thinking:还是不懂·~~~,看来要去看书了,,谢谢,沐神


#45

请问这里forward函数手动添加dense层 是什么含义? 已经forward 两层了为什么返回调用第一层?


#46

怎么自定义权重矩阵,完成矩阵运算???

下面是教程里面的代码:

def __init__(self, **kwargs):
    super(FancyMLP, self).__init__(**kwargs)
    with self.name_scope():
        self.dense = nn.Dense(256)
        self.weight = nd.random_uniform(shape=(256,20))

def forward(self, x):
    x = nd.relu(self.dense(x))
    x = nd.relu(nd.dot(x, self.weight)+1)
    x = nd.relu(self.dense(x))
    return x

发现self.weight不会作为模型参数被学习。
这样修改的self.weight = self.params.get(‘my_weight’, shape=((256,20))) 可以作为模型参数,却不能够参与nd.dot运算,会报错:
AssertionError: Argument rhs must have NDArray type, but got Parameter fancymlp4_my_weight (shape=(256, 20), dtype=<class ‘numpy.float32’>)


#47

请问 视频里老师每次运行都显示运行时间是怎么做到的?


就像这样


#48

Dense继承Block,nn.Block类里实现了__call__,实例会变成可调用对象

def __call__(self, *args):
    """Calls forward. Only accepts positional arguments."""
    return self.forward(*args)

def forward(self, *args):
    Parameters
    ----------
    *args : list of NDArray
        Input tensors.
    """
    # pylint: disable= invalid-name
    raise NotImplementedError

#49

http://zh.gluon.ai/chapter_prerequisite/install.html

运行计时
我们可以通过ExecutionTime插件来对每个cell的运行计时。

pip install jupyter_contrib_nbextensions
jupyter contrib nbextension install --user
jupyter nbextension enable execute_time/ExecuteTime

#50

哦哦 知道了 谢谢


#51
class MySequential(nn.Block):
    def __init__(self, **kwargs):
        super(MySequential, self).__init__(**kwargs)

    def add(self, block):
        # block 是一个 Block 子类实例,假设它有一个独一无二的名字。我们将它保存在
        # Block 类的成员变量 _children 里,其类型是 OrderedDict. 当调用
        # initialize 函数时,系统会自动对 _children 里面所有成员初始化。
        self._children[block.name] = block

    def forward(self, x):
        # OrderedDict 保证会按照插入时的顺序便利元素。
        for block in self._children.values():
            x = block(x)
        return x

这里的 “self._children”类型写的是OrderedDict,但在实际运行的时候变成了列表,print输出看到的也时列表格式,并且下面的运行报错。

error

请问这是怎么回事呢?


#52

对于文档中x = self.dense(x) “重用了 dense,等价于两层网络但共享了参数” 怎么直观的解释,实验如下:

结论:
1、FancyMLP()中的self.weight的列数与x中的列数必须相等
2、net.add(NestMLP(),nn.Dense(3),FancyMLP())中的nn.Dense(3)中的3必须与FancyMLP()中的self.weight的列数相等

过程:
1、将self.weight的列数随便写的,运行的时候报错。提示forward()函数中的第2个 x = self.dense(x) 矩阵维数不匹配。我记得nn.Dense()这个函数是不限制输入的,怎么会出现这种情况。看了文档中的注释,明白了这两个self.dense(x)的输入矩阵的维数应该保持一致。于是将self.weight的列数与输入x的列数改为一致,果然没有问题了
2、继续学习NestMLP(),在net.add(NestMLP(),nn.Dense(3),FancyMLP())中,首先是将nn.Dense(3)中的3写的是20,与文档保持一致,运行的时候报错,提示FancyMLP()中forward()函数第2个 x = self.dense(x) 矩阵维数不匹配。于是将FancyMLP()中的self.weight的列数改为了20.然后运行通过
3、接着又运行了FancyMLP()构造的net(x),毋庸置疑,又出现了同样的问题。想了想才明白过来net.add(NestMLP(),nn.Dense(20),FancyMLP())中nn.Dense(20)的输出是FancyMLP()的输入。因此nn.Dense(20)的输出应该与self.weight的列数保持一致,于是将20改为3,将问题1、2都解决了


#53

这个好像就是列表,我看了nn.Block类的定义,为什么说是字典呢?我也不明白,你最好发现是什么原因呢?


#54

请问有解决这个问题吗?


#55

遇到了同样的问题,这是什么原因,是mxnet版本的问题吗@szha


#56

也遇到了这个问题查看了 source code 更改了命令运行通过了,非常清奇的错误…很无语

def add(self, block):
self.register_child(block)


#57

求问 FancyMLP() 函数模块报错:

class FancyMLP(nn.Block):
    def __init__(self, **kwargs):
        super(FancyMLP, self).__init__(**kwargs)
        # 使用 get_constant 创建的随机权重参数不会在训练中被迭代(即常数参数)。
        self.rand_weight = self.params.get_constant(
             'rand_weight', nd.random.uniform(shape=(20, 20)))
        self.dense = nn.Dense(20, activation='relu')

照着教程自己敲在.py script中的, 结果运行时出现报错:
AttributeError: ‘ParameterDict’ object has no attribute ‘get_constant’

我查了 API 的source code 发现确确实实是有get_constant() 函数的,但是调用的时候还是出错…求大神解答

万分感谢!


#58

你更新一下mxnet到1.2.0?


#59

啊我的 mxnet 已经是1.2.0最新版本了…

我昨天看了源代码改掉了…
改成 self.params.get(‘rand_weight’), shape=(2,20))就可以运行了…

教程太旧了很多 bug 都是因为源代码改了但是教程根本就没有更新…


#60

感谢大神的帮助…


#61

变动好严重啊,难受


#62

教程中在构建MLP类时,继承的父类名是nn.block,但是我在网站上查询文档,找不到nn.block类,只有gluon.block类,请问这个如何理解?


#63

因为代码中有这样一句
from mxnet.gluon import nn
可以理解为nn是mxnet.gluon的简称,别名