forked from mindspore-Ecosystem/mindspore
413 lines
12 KiB
Python
413 lines
12 KiB
Python
# Copyright 2020 Huawei Technologies Co., Ltd
|
||
#
|
||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||
# you may not use this file except in compliance with the License.
|
||
# You may obtain a copy of the License at
|
||
#
|
||
# http://www.apache.org/licenses/LICENSE-2.0
|
||
#
|
||
# Unless required by applicable law or agreed to in writing, software
|
||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
# See the License for the specific language governing permissions and
|
||
# limitations under the License.
|
||
# ============================================================================
|
||
"""Generate vm_impl function for nn ops"""
|
||
import numpy as np
|
||
|
||
from mindspore.common.tensor import Tensor
|
||
from mindspore.ops import operations as P
|
||
from mindspore.ops.operations import _grad_ops as G
|
||
from mindspore.ops.vm_impl_registry import vm_impl_registry as vm_impl_getters
|
||
from .vm_interface import vm
|
||
|
||
|
||
# pylint: disable=unused-argument
|
||
|
||
|
||
@vm_impl_getters.register(P.ScalarSummary)
|
||
def vm_impl_scalar_summary(self):
|
||
"""Generate vm_impl function for ScalarSummary"""
|
||
|
||
def vm_impl(string_in, scalar):
|
||
"""Implement by vm mode."""
|
||
return scalar
|
||
|
||
return vm_impl
|
||
|
||
|
||
@vm_impl_getters.register(P.ReLU)
|
||
def vm_impl_relu(self):
|
||
"""Generate vm_impl function for ReLU"""
|
||
|
||
def vm_impl(x):
|
||
x = x.asnumpy()
|
||
output = Tensor(vm.relu(x))
|
||
return output
|
||
|
||
return vm_impl
|
||
|
||
|
||
@vm_impl_getters.register(P.Flatten)
|
||
def vm_impl_flatten(self):
|
||
"""Generate vm_impl function for Flatten"""
|
||
|
||
def vm_impl(x):
|
||
x = x.asnumpy()
|
||
return Tensor(vm.flatten_batch(x))
|
||
|
||
return vm_impl
|
||
|
||
|
||
@vm_impl_getters.register(P.Softmax)
|
||
def vm_impl_softmax(self):
|
||
"""Generate vm_impl function for Softmax"""
|
||
|
||
def vm_impl(x):
|
||
x = x.asnumpy()
|
||
return Tensor(vm.softmax(x))
|
||
|
||
return vm_impl
|
||
|
||
|
||
@vm_impl_getters.register(P.LogSoftmax)
|
||
def vm_impl_log_softmax(self):
|
||
"""Generate vm_impl function for LogSoftmax"""
|
||
|
||
def vm_impl(x):
|
||
x = x.asnumpy()
|
||
return Tensor(vm.logsoftmax(x))
|
||
|
||
return vm_impl
|
||
|
||
|
||
@vm_impl_getters.register(P.Tanh)
|
||
def vm_impl_tanh(self):
|
||
"""Generate vm_impl function for Tanh"""
|
||
|
||
def vm_impl(x):
|
||
x = x.asnumpy()
|
||
return Tensor(vm.tanh(x))
|
||
|
||
return vm_impl
|
||
|
||
|
||
@vm_impl_getters.register(P.FusedBatchNorm)
|
||
def vm_impl_fused_batch_norm(self):
|
||
"""Generate vm_impl function for FusedBatchNorm"""
|
||
|
||
def vm_impl(x, scale, b, mean, variance):
|
||
# pylint: disable=unused-argument
|
||
x = x.asnumpy()
|
||
scale = scale.asnumpy()
|
||
b = b.asnumpy()
|
||
mean = mean.asnumpy()
|
||
variance = variance.asnumpy()
|
||
out, x_mean, x_var, running_mean, running_var = vm.batch_norm(x, scale, b, mean, \
|
||
variance, \
|
||
eps=self.epsilon, \
|
||
momentum=self.momentum)
|
||
return Tensor(out), Tensor(x_mean), Tensor(x_var), \
|
||
Tensor(running_mean), Tensor(running_var)
|
||
|
||
return vm_impl
|
||
|
||
|
||
@vm_impl_getters.register(P.BatchNorm)
|
||
def vm_impl_batch_norm(self):
|
||
"""Generate vm_impl function for BatchNorm"""
|
||
|
||
def vm_impl(x, scale, b, mean, variance):
|
||
# pylint: disable=unused-argument
|
||
x = x.asnumpy()
|
||
scale = scale.asnumpy()
|
||
b = b.asnumpy()
|
||
mean = mean.asnumpy()
|
||
variance = variance.asnumpy()
|
||
out, x_mean, x_var, running_mean, running_var = vm.batch_norm(x, scale, b, mean, \
|
||
variance, \
|
||
eps=self.epsilon)
|
||
return Tensor(out), Tensor(x_mean), Tensor(x_var), \
|
||
Tensor(running_mean), Tensor(running_var)
|
||
|
||
return vm_impl
|
||
|
||
|
||
@vm_impl_getters.register(P.Conv2D)
|
||
def vm_impl_conv2d(self):
|
||
"""Generate vm_impl function for Conv2D"""
|
||
|
||
def vm_impl(x, w):
|
||
x = x.asnumpy()
|
||
weight = w.asnumpy()
|
||
bias = None
|
||
out = vm.conv2d(x, weight, bias, self.stride, self.pad, self.dilation)
|
||
return Tensor(out)
|
||
|
||
return vm_impl
|
||
|
||
|
||
@vm_impl_getters.register(G.MaxPoolGradWithArgmax)
|
||
def vm_impl_max_pool_grad_with_argmax(self):
|
||
"""Generate vm_impl function for MaxPoolGradWithArgmax"""
|
||
|
||
def vm_impl(x, dout, argmax):
|
||
x = x.asnumpy()
|
||
dout = dout.asnumpy()
|
||
arg_max = argmax.asnumpy()
|
||
dx = vm.max_pool_grad_with_argmax(x, dout, arg_max,
|
||
self.ksize[1], self.ksize[2], self.strides[1])
|
||
return Tensor(dx)
|
||
|
||
return vm_impl
|
||
|
||
|
||
@vm_impl_getters.register(P.MaxPoolWithArgmax)
|
||
def vm_impl_max_pool_with_argmax(self):
|
||
"""Generate vm_impl function for MaxPoolWithArgmax"""
|
||
|
||
def vm_impl(x):
|
||
x = x.asnumpy()
|
||
out, out_argmax = vm.max_pool_with_argmax(x, self.ksize[1], self.ksize[2], self.strides[1])
|
||
return Tensor(out), Tensor(out_argmax)
|
||
|
||
return vm_impl
|
||
|
||
|
||
@vm_impl_getters.register(P.MaxPool)
|
||
def vm_impl_max_pool(self):
|
||
"""Generate vm_impl function for MaxPool"""
|
||
|
||
def vm_impl(x):
|
||
x = x.asnumpy()
|
||
out = vm.max_pooling(x, self.ksize[-2], self.ksize[-1], self.strides[-2])
|
||
return Tensor(out)
|
||
|
||
return vm_impl
|
||
|
||
|
||
@vm_impl_getters.register(G.MaxPoolGrad)
|
||
def vm_impl_max_pool_grad(self):
|
||
"""Generate vm_impl function for MaxPoolGrad"""
|
||
|
||
def vm_impl(x, out, dout):
|
||
x = x.asnumpy()
|
||
dout = dout.asnumpy()
|
||
out = vm.max_pool_grad(x, dout, self.ksize[-2], self.ksize[-1], self.strides[-2])
|
||
return Tensor(out)
|
||
|
||
return vm_impl
|
||
|
||
|
||
@vm_impl_getters.register(P.AvgPool)
|
||
def vm_impl_avg_pool(self):
|
||
"""Generate vm_impl function for AvgPool"""
|
||
|
||
def vm_impl(x):
|
||
x = x.asnumpy()
|
||
out = vm.avg_pooling(x, self.ksize[-2], self.ksize[-1], self.strides[-2])
|
||
return Tensor(out)
|
||
|
||
return vm_impl
|
||
|
||
|
||
@vm_impl_getters.register(G.AvgPoolGrad)
|
||
def vm_impl_avg_pool_grad(self):
|
||
"""Generate vm_impl function for AvgPoolGrad"""
|
||
|
||
def vm_impl(dout, origin_shape):
|
||
dout = dout.asnumpy()
|
||
out = vm.avg_pool_grad(dout, origin_shape, self.ksize[-2], self.ksize[-1], self.strides[-2])
|
||
return Tensor(out)
|
||
|
||
return vm_impl
|
||
|
||
|
||
@vm_impl_getters.register(G.FusedBatchNormGrad)
|
||
def vm_impl_fused_batch_norm_grad(self):
|
||
"""Generate vm_impl function for FusedBatchNormGrad"""
|
||
|
||
def vm_impl(dy, x, scale, save_mean, save_inv_variance):
|
||
dy = dy.asnumpy()
|
||
x = x.asnumpy()
|
||
scale = scale.asnumpy()
|
||
save_mean = save_mean.asnumpy()
|
||
save_inv_variance = save_inv_variance.asnumpy()
|
||
dx, dscale, dshift = vm.batch_norm_grad(dy, x, scale, save_mean, save_inv_variance)
|
||
return (Tensor(dx), Tensor(dscale), Tensor(dshift))
|
||
|
||
return vm_impl
|
||
|
||
|
||
@vm_impl_getters.register(G.BatchNormGrad)
|
||
def vm_impl_fused_batch_norm_grad(self):
|
||
"""Generate vm_impl function for BatchNormGrad"""
|
||
|
||
def vm_impl(dy, x, scale, save_mean, save_inv_variance):
|
||
dy = dy.asnumpy()
|
||
x = x.asnumpy()
|
||
scale = scale.asnumpy()
|
||
save_mean = save_mean.asnumpy()
|
||
save_inv_variance = save_inv_variance.asnumpy()
|
||
dx, dscale, dshift = vm.batch_norm_grad(dy, x, scale, save_mean, save_inv_variance)
|
||
return (Tensor(dx), Tensor(dscale), Tensor(dshift))
|
||
|
||
return vm_impl
|
||
|
||
|
||
@vm_impl_getters.register(G.ReluGrad)
|
||
def vm_impl_relu_grad(self):
|
||
"""Generate vm_impl function for ReluGrad"""
|
||
|
||
def vm_impl(y_backprop, x):
|
||
x = x.asnumpy()
|
||
y_backprop = y_backprop.asnumpy()
|
||
y_backprop = vm.relu_grad(x.copy()) * y_backprop
|
||
return Tensor(y_backprop)
|
||
|
||
return vm_impl
|
||
|
||
|
||
@vm_impl_getters.register(P.Conv2DBackpropInput)
|
||
def vm_impl_conv2d_backprop_input(self):
|
||
"""Generate vm_impl function for Conv2DBackpropInput"""
|
||
|
||
def vm_impl(dout, w, x_size):
|
||
dout = dout.asnumpy()
|
||
w = w.asnumpy()
|
||
dx = vm.conv2d_backprop_input(dout, x_size, w, self.stride, self.pad)
|
||
return Tensor(dx)
|
||
|
||
return vm_impl
|
||
|
||
|
||
@vm_impl_getters.register(G.Conv2DBackpropFilter)
|
||
def vm_impl_conv2d_backprop_filter(self):
|
||
"""Generate vm_impl function for Conv2DBackpropFilter"""
|
||
|
||
def vm_impl(dout, x, w_size):
|
||
x = x.asnumpy()
|
||
dout = dout.asnumpy()
|
||
dw = vm.conv2d_backprop_filter(dout, x, w_size, self.stride, self.pad)
|
||
return Tensor(dw)
|
||
|
||
return vm_impl
|
||
|
||
|
||
@vm_impl_getters.register(G.FlattenGrad)
|
||
def vm_impl_flatten_grad(self):
|
||
"""Generate vm_impl function for FlattenGrad"""
|
||
|
||
def vm_impl(dout, x):
|
||
dout = dout.asnumpy()
|
||
dout = vm.flatten_grad(dout, x)
|
||
return Tensor(dout)
|
||
|
||
return vm_impl
|
||
|
||
|
||
@vm_impl_getters.register(P.BiasAdd)
|
||
def vm_impl_bias_add(self):
|
||
"""Generate vm_impl function for BiasAdd"""
|
||
|
||
def vm_impl(wx, bias):
|
||
wx = wx.asnumpy()
|
||
bias = bias.asnumpy()
|
||
out = wx + bias
|
||
return Tensor(out)
|
||
|
||
return vm_impl
|
||
|
||
|
||
@vm_impl_getters.register(G.BiasAddGrad)
|
||
def vm_impl_bias_add_grad(self):
|
||
"""Generate vm_impl function for BiasAddGrad"""
|
||
|
||
def vm_impl(dout):
|
||
dout = dout.asnumpy()
|
||
shape = np.shape(dout)
|
||
return Tensor(np.add.reduce(dout, axis=tuple(range(len(shape) - 1))))
|
||
|
||
return vm_impl
|
||
|
||
|
||
@vm_impl_getters.register(P.SoftmaxCrossEntropyWithLogits)
|
||
def vm_impl_softmax_cross_entropy_with_logits(self):
|
||
"""Generate vm_impl function for SoftmaxCrossEntropyWithLogits"""
|
||
|
||
def vm_impl(logits, labels):
|
||
logits = logits.asnumpy()
|
||
labels = labels.asnumpy()
|
||
loss, dx = vm.softmax_cross_entropy_with_logits(logits, labels)
|
||
return (Tensor(np.array(loss)), Tensor(dx))
|
||
|
||
return vm_impl
|
||
|
||
|
||
@vm_impl_getters.register(P.SparseSoftmaxCrossEntropyWithLogits)
|
||
def vm_impl_sparse_softmax_cross_entropy_with_logits(self):
|
||
"""Generate vm_impl function for SparseSoftmaxCrossEntropyWithLogits"""
|
||
|
||
def vm_impl(logits, labels):
|
||
logits = logits.asnumpy()
|
||
labels = labels.asnumpy()
|
||
|
||
n_class = labels.max() + 1
|
||
n_sample = labels.shape[0]
|
||
one_hot_label = np.zeros((n_sample, n_class)) # 3个样本,4个类别
|
||
one_hot_label[:, labels] = 1 # 非零列赋值为1
|
||
loss, dx = vm.softmax_cross_entropy_with_logits(logits, one_hot_label)
|
||
if self.is_grad:
|
||
return (Tensor(dx),)
|
||
return (Tensor(np.array(loss)),)
|
||
|
||
return vm_impl
|
||
|
||
|
||
@vm_impl_getters.register(P.ApplyMomentum)
|
||
def vm_impl_momentum(self):
|
||
"""Generate vm_impl function for Momentum"""
|
||
|
||
def vm_impl(variable,
|
||
accumulation,
|
||
learning_rate,
|
||
gradient,
|
||
momentum,
|
||
use_nesterov=False):
|
||
gradient = gradient.asnumpy()
|
||
accumulation = accumulation.asnumpy()
|
||
variable = variable.asnumpy()
|
||
shape = accumulation.shape
|
||
learning_rate = np.full(shape, learning_rate.asnumpy())
|
||
momentum = np.full(shape, momentum.asnumpy())
|
||
accumulation = accumulation * momentum + gradient
|
||
if use_nesterov is True:
|
||
variable -= gradient * learning_rate + accumulation * momentum * learning_rate
|
||
else:
|
||
variable -= accumulation * learning_rate
|
||
return Tensor(variable)
|
||
|
||
return vm_impl
|
||
|
||
|
||
@vm_impl_getters.register(P.ResizeBilinear)
|
||
def vm_impl_resize_bilinear(self):
|
||
"""Generate vm_impl function for ResizeBilinear"""
|
||
|
||
def vm_impl(x):
|
||
out = vm.ResizeBilinear(x)
|
||
return Tensor(out)
|
||
|
||
return vm_impl
|
||
|
||
|
||
@vm_impl_getters.register(G.ResizeBilinearGrad)
|
||
def vm_impl_resize_bilinear_grad(self):
|
||
"""Generate vm_impl function for ResizeBilinearGrad"""
|
||
|
||
def vm_impl(dout, original_image):
|
||
out = vm.ResizeBilinearGrad(dout, original_image)
|
||
return Tensor(out)
|
||
|
||
return vm_impl
|