forked from mindspore-Ecosystem/mindspore
!30269 optimizes the documentation of chinese API of RNN,Tiru,Unfold,etc
Merge pull request !30269 from zhangfanghe/code_docs_zfh_20220219_nn
This commit is contained in:
commit
6390b71296
|
@ -0,0 +1,42 @@
|
|||
mindspore.nn.Pad
|
||||
=================
|
||||
|
||||
.. py:class:: mindspore.nn.Pad(paddings, mode='CONSTANT')
|
||||
|
||||
根据 `paddings` 和 `mode` 对输入进行填充。
|
||||
|
||||
**参数:**
|
||||
|
||||
- **paddings** (tuple) - 填充大小,其shape为(N, 2),N是输入数据的维度,填充的元素为int类型。对于 `x` 的第 `D` 个维度,paddings[D, 0]表示要在输入Tensor的第 `D` 个维度之前扩展的大小,paddings[D, 1]表示在输入Tensor的第 `D` 个维度后面要扩展的大小。输出的每个维度D的填充大小为: :math:`paddings[D, 0] + input\_x.dim\_size(D) + paddings[D, 1]`
|
||||
|
||||
.. code-block::
|
||||
|
||||
# 假设参数和输入如下:
|
||||
mode = "CONSTANT".
|
||||
paddings = [[1,1], [2,2]].
|
||||
x = [[1,2,3], [4,5,6], [7,8,9]].
|
||||
# `x` 的第一个维度为3, `x` 的第二个维度为3。
|
||||
# 根据以上公式可得:
|
||||
# 输出的第一个维度是paddings[0][0] + 3 + paddings[0][1] = 1 + 3 + 1 = 5。
|
||||
# 输出的第二个维度是paddings[1][0] + 3 + paddings[1][1] = 2 + 3 + 2 = 7。
|
||||
# 所以最终的输出shape为(5, 7)
|
||||
|
||||
- **mode** (str) - 指定填充模式。取值为"CONSTANT","REFLECT","SYMMETRIC"。默认值:"CONSTANT"。
|
||||
|
||||
**输入:**
|
||||
|
||||
- **x** (Tensor) - 输入Tensor。
|
||||
|
||||
**输出:**
|
||||
|
||||
Tensor,填充后的Tensor。
|
||||
|
||||
- 如果 `mode` 为"CONSTANT", `x` 使用0进行填充。例如, `x` 为[[1,2,3],[4,5,6],[7,8,9]], `paddings` 为[[1,1],[2,2]],则输出为[[0,0,0,0,0,0,0],[0,0,1,2,3,0,0],[0,0,4,5,6,0,0],[0,0,7,8,9,0,0],[0,0,0,0,0,0,0]]。
|
||||
- 如果 `mode` 为"REFLECT", `x` 使用对称轴进行对称复制的方式进行填充(复制时不包括对称轴)。例如 `x` 为[[1,2,3],[4,5,6],[7,8,9]], `paddings` 为[[1,1],[2,2]],则输出为[[6,5,4,5,6,5,4],[3,2,1,2,3,2,1],[6,5,4,5,6,5,4],[9,8,7,8,9,8,7],[6,5,4,5,6,5,4]]。
|
||||
- 如果 `mode` 为"SYMMETRIC",此填充方法类似于"REFLECT"。也是根据对称轴填充,包含对称轴。例如 `x` 为[[1,2,3],[4,5,6],[7,8,9]], `paddings` 为[[1,1],[2,2]],则输出为[[2,1,1,2,3,3,2],[2,1,1,2,3,3,2],[5,4,4,5,6,6,5],[8,7,7,8,9,9,8],[8,7,7,8,9,9,8]]。
|
||||
|
||||
**异常:**
|
||||
|
||||
- **TypeError** - `paddings` 不是tuple。
|
||||
- **ValueError** - `paddings` 的长度超过4或其shape不是(n, 2)。
|
||||
- **ValueError** - `mode` 不是'CONSTANT','REFLECT'或'SYMMETRIC'。
|
|
@ -0,0 +1,20 @@
|
|||
mindspore.nn.RMSELoss
|
||||
======================
|
||||
|
||||
.. py:class:: mindspore.nn.RMSELoss
|
||||
|
||||
RMSELoss用来测量 :math:`x` 和 :math:`y` 元素之间的均方根误差,其中 :math:`x` 是输入Tensor, :math:`y` 是目标值。
|
||||
|
||||
假设 :math:`x` 和 :math:`y` 为一维Tensor,长度为 :math:`N` , :math:`x` 和 :math:`y` 的loss为:
|
||||
|
||||
.. math::
|
||||
loss = \sqrt{\frac{1}{N}\sum_{i=1}^{N}{(x_i-y_i)^2}}
|
||||
|
||||
**输入:**
|
||||
|
||||
- **logits** (Tensor) - 输入的预测值,任意维度的Tensor。
|
||||
- **labels** (Tensor) - 输入的目标值,任意维度的Tensor。一般与 `logits` 的shape相同。如果 `logits` 和 `labels` 的shape不同,需支持广播。
|
||||
|
||||
**输出:**
|
||||
|
||||
Tensor,输出值为加权损失值,其数据类型为float,其shape为0。
|
|
@ -0,0 +1,45 @@
|
|||
mindspore.nn.RNN
|
||||
=================
|
||||
|
||||
.. py:class:: mindspore.nn.RNN(*args, **kwargs)
|
||||
|
||||
循环神经网络(RNN)层,其使用的激活函数为tanh或relu。
|
||||
|
||||
对输入序列中的每个元素,每层的计算公式如下:
|
||||
|
||||
.. math::
|
||||
h_t = \tanh(W_{ih} x_t + b_{ih} + W_{hh} h_{(t-1)} + b_{hh})
|
||||
|
||||
这里的 :math:`h_t` 是在 `t` 时刻的隐藏状态, :math:`x_t`是在 `t` 时刻的输入, :math:`h_{(t-1)}` 是上一层在 `t-1` 时刻的隐藏状态,或在 `0` 时刻的初始隐藏状态。如果 ``nonlinearity`` 是'relu',则使用 :math:`\text{ReLU}` 而不是 :math:`\tanh` 。
|
||||
|
||||
**参数:**
|
||||
|
||||
- **input_size** (int) - 输入层输入的特征向量维度。
|
||||
- **hidden_size** (int) - 隐藏层输出的特征向量维度。
|
||||
- **num_layers** (int) - 堆叠RNN的层数。默认值:1。
|
||||
- **nonlinearity** (str) - 用于选择非线性激活函数。取值可为'tanh'或'relu'。默认值:'tanh'。
|
||||
- **has_bias** (bool) - Cell是否有偏置项 `b_ih` 和 `b_hh` 。默认值:True。
|
||||
- **batch_first** (bool) - 指定输入 `x` 的第一个维度是否为batch_size。默认值:False。
|
||||
- **dropout** (float) - 指的是除第一层外每层输入时的Dropout概率。Dropout的范围为[0.0, 1.0)。默认值0.0。
|
||||
- **bidirectional** (bool) - 指定是否为双向RNN,如果bidirectional=True,则num_directions=2,否则为1。默认值:False。
|
||||
|
||||
**输入:**
|
||||
|
||||
- **x** (Tensor) - 数据类型为mindspore.float32或mindspore.float16,shape为(seq_len, batch_size, `input_size`)或(batch_size, seq_len, `input_size`)的Tensor。
|
||||
- **hx** (Tensor) - 数据类型为mindspore.float32或mindspore.float16,shape为(num_directions * `num_layers`, batch_size, `hidden_size`)的Tensor。 `hx` 的数据类型与 `x` 相同。
|
||||
- **seq_length** (Tensor) - 输入batch的序列长度,Tensor的shape为 :math:`(\text{batch_size})` 。此输入指明真实的序列长度,以避免使用填充后的元素计算隐藏状态,影响最后的输出。当**x**被填充元素时,建议使用此输入。默认值:None。
|
||||
|
||||
**输出:**
|
||||
|
||||
Tuple,包含(`output`, `h_n`)的tuple。
|
||||
|
||||
- **output** (Tensor) - shape为(seq_len, batch_size, num_directions * `hidden_size`)或(batch_size, seq_len, num_directions * `hidden_size`)的Tensor。
|
||||
- **hx_n** (Tensor) - shape为(num_directions * `num_layers` , batch_size, `hidden_size`)的Tensor。
|
||||
|
||||
**异常:**
|
||||
|
||||
- **TypeError** - `input_size` , `hidden_size` 或 `num_layers` 不是int。
|
||||
- **TypeError** - `has_bias` , `batch_first` 或 `bidirectional` 不是bool。
|
||||
- **TypeError** - `dropout` 不是float。
|
||||
- **ValueError** - `dropout` 不在[0.0, 1.0)范围内。
|
||||
- **ValueError** - `nonlinearity` 不在['tanh', 'relu']中。
|
|
@ -0,0 +1,35 @@
|
|||
mindspore.nn.RNNCell
|
||||
=====================
|
||||
|
||||
.. py:class:: mindspore.nn.RNNCell(input_size: int, hidden_size: int, has_bias: bool = True, nonlinearity: str = 'tanh')
|
||||
|
||||
用于定义循环神经网络(RNN)的一个单元,激活函数是tanh或relu。
|
||||
|
||||
.. math::
|
||||
h_t = \tanh(W_{ih} x_t + b_{ih} + W_{hh} h_{(t-1)} + b_{hh})
|
||||
|
||||
其中 :math:`h_t` 是在 `t` 时刻的隐藏状态, :math:`x_t` 是在 `t` 时刻的输入, :math:`h_{(t-1)}` 是在 `t-1` 时刻的隐藏状态,或在 `0` 时刻的初始隐藏状态。
|
||||
|
||||
如果 `nonlinearity` 是'relu',则使用'relu'而不是'tanh'。
|
||||
|
||||
**参数:**
|
||||
|
||||
- **input_size** (int) - 输入层输入的特征向量维度。
|
||||
- **hidden_size** (int) - 隐藏层输出的特征向量维度。
|
||||
- **has_bias** (bool) - Cell是否有偏置项 `b_ih` 和 `b_hh` 。默认值:True。
|
||||
- **nonlinearity** (str) - 用于选择非线性激活函数。取值可以是'tanh'或'relu'。默认值:'tanh'。
|
||||
|
||||
**输入:**
|
||||
|
||||
- **x** (Tensor) - 输入Tensor,其shape为(batch_size, `input_size`)。
|
||||
- **hx** (Tensor) - 输入Tensor,其数据类型为mindspore.float32及shape为(batch_size, `hidden_size`)。 `hx` 的数据类型与 `x` 相同。
|
||||
|
||||
**输出:**
|
||||
|
||||
- **hx'** (Tensor) - shape为(batch_size, `hidden_size`)的Tensor。
|
||||
|
||||
**异常:**
|
||||
|
||||
- **TypeError** - `input_size` 或 `hidden_size` 不是int或不大于0。
|
||||
- **TypeError** - `has_bias` 不是bool。
|
||||
- **ValueError** - `nonlinearity` 不在['tanh', 'relu']中。
|
|
@ -0,0 +1,23 @@
|
|||
mindspore.nn.ReLU6
|
||||
===================
|
||||
|
||||
.. py:class:: mindspore.nn.ReLU6
|
||||
|
||||
ReLU6激活函数。
|
||||
|
||||
ReLU6类似于ReLU,不同之处在于设置了上限,其上限为6,如果输入大于6,输出会被限制为6。公式如下:
|
||||
|
||||
.. math::
|
||||
\min(\max(0, x), 6).
|
||||
|
||||
**输入:**
|
||||
|
||||
- **x** (Tensor) - ReLU6的输入,任意维度的Tensor,其数据类型为float16或float32的。
|
||||
|
||||
**输出:**
|
||||
|
||||
Tensor,数据类型与 `x` 相同。
|
||||
|
||||
**异常:**
|
||||
|
||||
- **TypeError** - `x` 的数据类型既不是float16也不是float32。
|
|
@ -0,0 +1,30 @@
|
|||
mindspore.nn.ResizeBilinear
|
||||
============================
|
||||
|
||||
.. py:class:: mindspore.nn.ResizeBilinear
|
||||
|
||||
使用双线性插值调整输入Tensor为指定的大小。
|
||||
|
||||
**输入:**
|
||||
|
||||
- **x** (Tensor) - ResizeBilinear的输入,四维的Tensor,其shape为 :math:`(batch, channels, height, width)` ,数据类型为float16或float32。
|
||||
- **size** (Union[tuple[int], list[int], None]) - 指定新Tensor的大小,其shape为 :math:`(new\_height, new\_width)` 的tuple或者list。只有size或scale_factor能设置为None。默认值:None。
|
||||
- **scale_factor** (int, None) - 新Tensor大小的缩放因子,其值为正整数。只有size或scale_factor能设置为None。默认值:None。
|
||||
- **align_corners** (bool) - 如果为True,将使用 :math:`(new\_height - 1) / (height - 1)` 来调整输入,这将精确对齐图像的4个角以及调整图像大小。如果为False,将使用 :math:`new\_height / height` 来调整。默认值:False。
|
||||
|
||||
**输出:**
|
||||
|
||||
调整后的Tensor。
|
||||
|
||||
如果设置了size,则结果为 :math:`(batch, channels, new\_height, new\_width)` 的四维Tensor,其数据类型与 `x` 相同。如果设置了scale,则结果为 :math:`(batch, channels, scale\_factor * height, scale\_factor * width)` 的四维Tensor,其数据类型与 `x` 相同。
|
||||
|
||||
**异常:**
|
||||
|
||||
- **TypeError** - `size` 不是tuple、list或None。
|
||||
- **TypeError** - `scale_factor` 既不是int也不是None。
|
||||
- **TypeError** - `align_corners` 不是bool。
|
||||
- **TypeError** - `x` 的数据类型既不是float16也不是float32。
|
||||
- **ValueError** - `size` 和 `scale_factor` 都为None或都不为None。
|
||||
- **ValueError** - `x` 的shape长度不等于4。
|
||||
- **ValueError** - `scale_factor` 是小于0的int。
|
||||
- **ValueError** - `size` 是长度不等于2的list或tuple。
|
|
@ -0,0 +1,37 @@
|
|||
mindspore.nn.SampledSoftmaxLoss
|
||||
================================
|
||||
|
||||
.. py:class:: mindspore.nn.SampledSoftmaxLoss(num_sampled, num_classes, num_true=1, sampled_values=None, remove_accidental_hits=True, seed=0, reduction='none')
|
||||
|
||||
抽样交叉熵损失函数。
|
||||
|
||||
一般在类别数很大时使用,可加速训练交叉熵分类器。
|
||||
|
||||
**参数:**
|
||||
|
||||
- **num_sampled** (int) - 抽样的类别数。
|
||||
- **num_classes** (int) - 类别总数。
|
||||
- **num_true** (int):每个训练样本的类别数。默认值:1。
|
||||
- **sampled_values** (Union[list, tuple]) - 抽样候选值。由 `*CandidateSampler` 函数返回的(`sampled_candidates`, `true_expected_count` , `sampled_expected_count`)的list或tuple。如果默认值为None,则应用 `UniformCandidateSampler` 。
|
||||
- **remove_accidental_hits** (bool) - 是否移除抽样中的目标类等于标签的情况。默认值:True。
|
||||
- **seed** (int) - 抽样的随机种子。默认值:0。
|
||||
- **reduction** (str) - 指定应用于输出结果的计算方式。取值为"mean","sum",或"none"。取值为"none",则不执行reduction。默认值:"none"。
|
||||
|
||||
**输入:**
|
||||
|
||||
- **weights** (Tensor) - 输入的权重,shape为 :math:`(C, dim)` 的Tensor。
|
||||
- **bias** (Tensor) - 分类的偏置。shape为 :math:`(C,)` 的Tensor。
|
||||
- **labels** (Tensor) - 输入目标值Tensor,其shape为 :math:`(N, num\_true)` ,其数据类型为 `int64, int32` 。
|
||||
- **logits** (Tensor) - 输入预测值Tensor,其shape为 :math:`(N, dim)` 。
|
||||
|
||||
**输出:**
|
||||
|
||||
Tensor或Scalar,如果 `reduction` 为'none',则输出是shape为 :math:`(N,)` 的Tensor。否则,输出为Scalar。
|
||||
|
||||
**异常:**
|
||||
|
||||
- **TypeError** - `sampled_values` 不是list或tuple。
|
||||
- **TypeError** - `labels` 的数据类型既不是int32,也不是int64。
|
||||
- **ValueError** - `reduction` 不为'none'、'mean'或'sum'。
|
||||
- **ValueError** - `num_sampled` 或 `num_true` 大于 `num_classes` 。
|
||||
- **ValueError** - `sampled_values` 的长度不等于3。
|
|
@ -0,0 +1,31 @@
|
|||
mindspore.nn.SoftMarginLoss
|
||||
============================
|
||||
|
||||
.. py:class:: mindspore.nn.SoftMarginLoss(reduction='mean')
|
||||
|
||||
针对二分类问题的损失函数。
|
||||
|
||||
SoftMarginLoss用于计算输入Tensor :math:`x` 和目标值Tensor :math:`y` (包含1或-1)的二分类损失值。
|
||||
|
||||
.. math::
|
||||
\text{loss}(x, y) = \sum_i \frac{\log(1 + \exp(-y[i]*x[i]))}{\text{x.nelement}()}
|
||||
|
||||
**参数:**
|
||||
|
||||
- **reduction** (str) - 指定应用于输出结果的计算方式。取值为"mean","sum",或"none"。默认值:"mean"。
|
||||
|
||||
**输入:**
|
||||
|
||||
- **logits** (Tensor) - 预测值,数据类型为float16或float32。
|
||||
- **labels** (Tensor) - 目标值,数据类型和shape与 `logits` 的相同。
|
||||
|
||||
**输出:**
|
||||
|
||||
Tensor或Scalar,如果 `reduction` 为"none",其shape与 `logits` 相同。否则,将返回scalar。
|
||||
|
||||
**异常:**
|
||||
|
||||
- **TypeError** - `logits` 或 `labels` 不是Tensor。
|
||||
- **TypeError** - `logits` 或 `labels` 的数据类型既不是float16也不是float32。
|
||||
- **ValueError** - `logits` 的shape与 `labels` 不同。
|
||||
- **ValueError** - `reduction` 不为"mean","sum",或"none"。
|
|
@ -0,0 +1,40 @@
|
|||
mindspore.nn.SoftmaxCrossEntropyWithLogits
|
||||
===========================================
|
||||
|
||||
.. py:class:: mindspore.nn.SoftmaxCrossEntropyWithLogits(sparse=False, reduction='none')
|
||||
|
||||
计算预测值与真实值之间的交叉熵。
|
||||
|
||||
使用交叉熵损失函数计算出输入概率(使用softmax函数计算)和真实值之间的误差。
|
||||
|
||||
对于每个实例 :math:`x_i` ,i的范围为0到N-1,则可得损失为:
|
||||
|
||||
.. math::
|
||||
\ell(x_i, c) = - \log\left(\frac{\exp(x_i[c])}{\sum_j \exp(x_i[j])}\right)
|
||||
= -x_i[c] + \log\left(\sum_j \exp(x_i[j])\right)
|
||||
|
||||
其中 :math:`x_i` 是一维的Tensor, :math:`c` 为one-hot中等于1的位置。
|
||||
|
||||
.. note::
|
||||
虽然目标值是互斥的,即目标值中只有一个为正,但预测的概率不为互斥。只要求输入的预测概率分布有效。
|
||||
|
||||
**参数:**
|
||||
|
||||
- **sparse** (bool) - 指定目标值是否使用稀疏格式。默认值:False。
|
||||
- **reduction** (str) - 指定应用于输出结果的计算方式。取值为"mean","sum",或"none"。取值为"none",则不执行reduction。默认值:"none"。
|
||||
|
||||
**输入:**
|
||||
|
||||
- **logits** (Tensor) - shape (N, C)的Tensor。数据类型为float16或float32。
|
||||
- **labels** (Tensor) - shape (N, )的Tensor。如果 `sparse` 为True,则 `labels` 的类型为int32或int64。否则,`labels` 的类型与 `logits` 的类型相同。
|
||||
|
||||
**输出:**
|
||||
|
||||
Tensor,一个shape和数据类型与logits相同的Tensor。
|
||||
|
||||
**异常:**
|
||||
|
||||
- **TypeError** - `sparse` 不是bool。
|
||||
- **TypeError** - `sparse` 为True,并且 `labels` 的dtype既不是int32,也不是int64。
|
||||
- **TypeError** - `sparse` 为False,并且 `labels` 的dtype既不是float16,也不是float32。
|
||||
- **ValueError** - `reduction` 不为"mean"、"sum",或"none"。
|
|
@ -0,0 +1,25 @@
|
|||
mindspore.nn.Triu
|
||||
==================
|
||||
|
||||
.. py:class:: mindspore.nn.Triu
|
||||
|
||||
返回一个Tensor,指定主对角线以下的元素被置为0。
|
||||
|
||||
将矩阵元素沿主对角线分为上三角和下三角(包含对角线)。
|
||||
|
||||
参数 `k` 控制对角线的选择。若 `k` 为0,则沿主对角线分割并保留上三角所有元素。若 `k` 为正值,则沿主对角线向上选择对角线 `k` ,并保留上三角所有元素。若 `k` 为负值,则沿主对角线向下选择对角线 `k` ,并保留上三角所有元素。
|
||||
|
||||
|
||||
**输入:**
|
||||
|
||||
- **x** (Tensor) - Triu的输入,任意维度的Tensor,其数据类型为Number。
|
||||
- **k** (Int) - 对角线的索引。默认值:0。
|
||||
|
||||
**输出:**
|
||||
|
||||
Tensor,数据类型和shape与 `x` 相同。
|
||||
|
||||
**异常:**
|
||||
|
||||
- **TypeError** - `k` 不是int。
|
||||
- **ValueError** - `x` 的shape长度小于1。
|
|
@ -0,0 +1,38 @@
|
|||
mindspore.nn.Unfold
|
||||
====================
|
||||
|
||||
.. py:class:: mindspore.nn.Unfold(ksizes, strides, rates, padding='valid')
|
||||
|
||||
从图像中提取滑窗的区域块。
|
||||
|
||||
输入为一个四维的Tensor,数据格式为NCHW。
|
||||
|
||||
**参数:**
|
||||
|
||||
- **ksizes** (Union[tuple[int], list[int]]):滑窗大小,其格式为[1, ksize_row, ksize_col, 1]的tuple或int列表。
|
||||
- **strides** (Union[tuple[int], list[int]]):滑窗步长,其格式为[1, stride_row, stride_col, 1]的tuple或int列表。
|
||||
- **rates** (Union[tuple[int], list[int]]):滑窗元素之间的空洞个数,其格式为[1, rate_row, rate_col, 1] 的tuple或整数list。
|
||||
- **padding** (str):填充模式,可选值有:"same"或"valid"的字符串,不区分大小写。默认值:"valid"。
|
||||
|
||||
- **same** - 指所提取的区域块的部分区域可以在原始图像之外,此部分填充为0。
|
||||
- **valid** - 表示所取的区域快必须被原始图像所覆盖。
|
||||
|
||||
**输入:**
|
||||
|
||||
- **x** (Tensor) - 输入四维Tensor, 其shape为[in_batch, in_depth, in_row, in_col],其数据类型为number。
|
||||
|
||||
**输出:**
|
||||
|
||||
Tensor,输出为四维Tensor,数据类型与 `x` 相同,其shape为[out_batch, out_depth, out_row, out_col],且 `out_batch` 与 `in_batch` 相同。
|
||||
|
||||
:math:`out\_depth = ksize\_row * ksize\_col * in\_depth`
|
||||
|
||||
:math:`out\_row = (in\_row - (ksize\_row + (ksize\_row - 1) * (rate\_row - 1))) // stride\_row + 1`
|
||||
|
||||
:math:`out\_col = (in\_col - (ksize\_col + (ksize\_col - 1) * (rate\_col - 1))) // stride\_col + 1`
|
||||
|
||||
**异常:**
|
||||
|
||||
- **TypeError** - `ksize` , `strides` 或 `rates` 既不是tuple,也不是list。
|
||||
- **ValueError** - `ksize` , `strides` 或 `rates` 的shape不是(1, x_row, x_col, 1)。
|
||||
- **ValueError** - `ksize` , `strides` 或 `rates` 的第二个和第三个元素小于1。
|
|
@ -0,0 +1,15 @@
|
|||
mindspore.nn.get_activation
|
||||
============================
|
||||
|
||||
.. py:function:: mindspore.nn.get_activation(name, prim_name=None)
|
||||
|
||||
获取激活函数。
|
||||
|
||||
**参数:**
|
||||
|
||||
- **name** (str) - 激活函数名称。
|
||||
- **prim_name** (Union[str, None]) - 算子名称,默认:None。
|
||||
|
||||
**返回:**
|
||||
|
||||
激活函数。
|
Loading…
Reference in New Issue