import numpy as np
import mindspore
from mindspore import ops
from mindspore import Tensor, CSRTensor, COOTensor
data = [1, 0, 1, 0]
x_data = Tensor(data)
print(x_data, x_data.shape, x_data.dtype)
np_array = np.array(data)
x_np = Tensor(np_array)
print(x_np, x_np.shape, x_np.dtype)
from mindspore.common.initializer import One, Normal
# Initialize a tensor with ones
tensor1 = mindspore.Tensor(shape=(2, 2), dtype=mindspore.float32, init=One())
# Initialize a tensor from normal distribution
tensor2 = mindspore.Tensor(shape=(2, 2), dtype=mindspore.float32, init=Normal())
print("tensor1:\n", tensor1)
print("tensor2:\n", tensor2)
from mindspore import ops
x_ones = ops.ones_like(x_data)
print(f"Ones Tensor: \n {x_ones} \n")
x_zeros = ops.zeros_like(x_data)
print(f"Zeros Tensor: \n {x_zeros} \n")
[1 0 1 0] (4,) Int64
[1 0 1 0] (4,) Int64
tensor1:
[[1. 1.]
[1. 1.]]
tensor2:
[[ 0.01097696 0.01645728]
[-0.00532449 -0.00663322]]
Ones Tensor:
[1 1 1 1]
Zeros Tensor:
[0 0 0 0]
x = Tensor(np.array([[1, 2], [3, 4]]), mindspore.int32)
print("x_shape:", x.shape)
print("x_dtype:", x.dtype)
print("x_itemsize:", x.itemsize)
print("x_nbytes:", x.nbytes)
print("x_ndim:", x.ndim)
print("x_size:", x.size)
print("x_strides:", x.strides)
x_shape: (2, 2)
x_dtype: Int32
x_itemsize: 4
x_nbytes: 16
x_ndim: 2
x_size: 4
x_strides: (8, 4)
tensor = Tensor(np.array([[0, 1], [2, 3]]).astype(np.float32))
print("First row: {}".format(tensor[0]))
print("value of bottom right corner: {}".format(tensor[1, 1]))
print("Last column: {}".format(tensor[:, -1]))
print("First column: {}".format(tensor[..., 0]))
First row: [0. 1.]
value of bottom right corner: 3.0
Last column: [1. 3.]
First column: [0. 2.]
x = Tensor(np.array([1, 2, 3]), mindspore.float32)
y = Tensor(np.array([4, 5, 6]), mindspore.float32)
output_add = x + y
output_sub = x - y
output_mul = x * y
output_div = y / x
output_mod = y % x
output_floordiv = y // x
print("add:", output_add)
print("sub:", output_sub)
print("mul:", output_mul)
print("div:", output_div)
print("mod:", output_mod)
print("floordiv:", output_floordiv)
data1 = Tensor(np.array([[0, 1], [2, 3]]).astype(np.float32))
data2 = Tensor(np.array([[4, 5], [6, 7]]).astype(np.float32))
output = ops.concat((data1, data2), axis=0)
print(output)
print("shape:\n", output.shape)
add: [5. 7. 9.]
sub: [-3. -3. -3.]
mul: [ 4. 10. 18.]
div: [4. 2.5 2. ]
mod: [0. 1. 0.]
floordiv: [4. 2. 2.]
[[0. 1.]
[2. 3.]
[4. 5.]
[6. 7.]]
shape:
(4, 2)
data1 = Tensor(np.array([[0, 1], [2, 3]]).astype(np.float32))
data2 = Tensor(np.array([[4, 5], [6, 7]]).astype(np.float32))
output = ops.stack([data1, data2])
print(output)
print("shape:\n", output.shape)
t = Tensor([1., 1., 1., 1., 1.])
print(f"t: {t}", type(t))
n = t.asnumpy()
print(f"n: {n}", type(n))
n = np.ones(5)
t = Tensor.from_numpy(n)
np.add(n, 1, out=n)
print(f"n: {n}", type(n))
print(f"t: {t}", type(t))
[[[0. 1.]
[2. 3.]]
[[4. 5.]
[6. 7.]]]
shape:
(2, 2, 2)
t: [1. 1. 1. 1. 1.] <class 'mindspore.common.tensor.Tensor'>
n: [1. 1. 1. 1. 1.] <class 'numpy.ndarray'>
n: [2. 2. 2. 2. 2.] <class 'numpy.ndarray'>
t: [2. 2. 2. 2. 2.] <class 'mindspore.common.tensor.Tensor'>
indptr = Tensor([0, 1, 2])
indices = Tensor([0, 1])
values = Tensor([1, 2], dtype=mindspore.float32)
shape = (2, 4)
# Make a CSRTensor
csr_tensor = CSRTensor(indptr, indices, values, shape)
print(csr_tensor.astype(mindspore.float64).dtype)
Float64
上述代码会生成如下所示的CSRTensor
:
[ 1 0 0 0 0 2 0 0 ] \left[ \begin{matrix} 1 & 0 & 0 & 0 \\ 0 & 2 & 0 & 0 \end{matrix} \right] [10020000]
这段代码展示了如何在MindSpore框架中使用稀疏矩阵表示法中的CSR(Compressed Sparse Row)格式来创建一个稀疏张量,并进一步将其数据类型转换为mindspore.float64
。下面是对代码的逐步解析:
数据结构介绍
在稀疏矩阵表示中,CSR格式是一种常用的方式,特别适合于行稀疏的矩阵。它由三个数组组成:
- indptr (indices pointer): 一个一维数组,表示每行开始的索引位置。最后一个元素通常表示超过最后一行的偏移量,从而间接给出矩阵的行数。
- indices: 一个一维数组,表示非零元素对应的列索引。
- values: 一个一维数组,存储了矩阵中的非零元素值,与
indices
一一对应。 - shape: 一个元组,表示矩阵的维度。
代码解析
- indptr = Tensor([0, 1, 2]): 表示有两行数据,第一行的非零元素从位置0开始,第二行的非零元素从位置1开始。由于没有第三个值,可以推断只有两行。
- indices = Tensor([0, 1]): 表示非零元素分别位于第0列和第1列。
- values = Tensor([1, 2], dtype=mindspore.float32): 存储非零元素的值,分别为1和2,且指定数据类型为32位浮点数。
- shape = (2, 4): 矩阵为2行4列。
创建CSRTensor
通过CSRTensor(indptr, indices, values, shape)
构造函数,将上述信息组合成一个CSRTensor对象,表示一个2x4的稀疏矩阵,其中有效元素为(0,0)=1和(1,1)=2。
数据类型转换
csr_tensor.astype(mindspore.float64)
这一行代码的作用是将csr_tensor
的数据类型转换为64位浮点数(mindspore.float64
)。.astype()
是MindSpore中用于改变Tensor数据类型的方法。
打印结果
print(csr_tensor.astype(mindspore.float64).dtype)
会输出转换后的数据类型,即mindspore.float64
,表明转换成功。
位置查找
至于“怎么找到位置”,在稀疏矩阵的CSR表示中,给定一个元素值,要找到它的位置(行和列索引),可以通过以下步骤:
- 确定行: 查找
indptr
来确定元素所在的行。具体来说,找到满足indptr[i] <= element_index < indptr[i+1]
的第一个i
,则元素位于第i
行。 - 确定列: 在
indices
数组中,元素的索引(相对于values
)指向其所在的列。即,如果元素在values
中的索引是j
,那么它位于第indices[j]
列。
例如,如果想找到值为2的位置,我们知道它在values
中的索引是1,因此它位于indices[1]
所指的列,即第1列;又因为它在values
中的第一个元素之后,根据indptr
,它属于第二行。因此,值2位于(1,1)的位置。
indices = Tensor([[0, 1], [1, 2]], dtype=mindspore.int32)
values = Tensor([1, 2], dtype=mindspore.float32)
shape = (3, 4)
# Make a COOTensor
coo_tensor = COOTensor(indices, values, shape)
print(coo_tensor.values)
print(coo_tensor.indices)
print(coo_tensor.shape)
print(coo_tensor.astype(mindspore.float64).dtype) # COOTensor to float64
[1. 2.]
[[0 1]
[1 2]]
(3, 4)
Float64
这段代码展示了在MindSpore框架中如何使用另一种稀疏矩阵表示法COO(Coordinate Format,坐标格式)来创建一个稀疏张量,并展示了如何访问其属性以及转换数据类型。下面是详细的解析:
COO格式简介
COO(Coordinate Format)格式是稀疏矩阵的一种存储方式,它直接存储非零元素的坐标(行索引和列索引)及对应的值。这种格式通过三个主要部分来表示稀疏矩阵:
- indices: 一个二维张量,每一行表示一个非零元素的行索引和列索引。
- values: 一个一维张量,存储了与
indices
中索引对应的非零元素的值。 - shape: 一个元组,表示稀疏矩阵的形状(行数和列数)。
代码解析
- indices = Tensor([[0, 1], [1, 2]], dtype=mindspore.int32): 表示有两个非零元素,它们的坐标分别是(0, 1)和(1, 2)。
- values = Tensor([1, 2], dtype=mindspore.float32): 这些坐标上的元素值分别是1和2。
- shape = (3, 4): 定义了稀疏矩阵的维度为3行4列。
创建COOTensor
通过COOTensor(indices, values, shape)
,利用给定的索引、值和形状创建了一个COO格式的稀疏张量。
访问属性
- coo_tensor.values: 输出非零元素的值,即
[1, 2]
。 - coo_tensor.indices: 输出非零元素的坐标,即
[[0, 1], [1, 2]]
。 - coo_tensor.shape: 输出稀疏矩阵的形状,即
(3, 4)
。
数据类型转换
coo_tensor.astype(mindspore.float64).dtype
: 将COOTensor的数据类型转换为64位浮点数,并打印转换后的数据类型,输出应为mindspore.float64
。
如何找到位置
在COO格式中,每个非零元素的位置(行和列)直接存储在indices
中:
- 查找元素位置: 假设要查找值为2的位置,首先在
values
中找到该值,它位于第1个位置。然后,在indices
的相应位置(即第1行)查看索引,得到[1, 2]
。这表示值2位于第1行第2列。
因此,对于COO张量,直接通过indices
属性就能快速获取到每个非零元素的确切位置(行号和列号)。
上述代码会生成如下所示的COOTensor
:
[ 0 1 0 0 0 0 2 0 0 0 0 0 ] \left[ \begin{matrix} 0 & 1 & 0 & 0 \\ 0 & 0 & 2 & 0 \\ 0 & 0 & 0 & 0 \end{matrix} \right] 000100020000
import numpy as np
from mindspore.dataset import vision
from mindspore.dataset import MnistDataset, GeneratorDataset
import matplotlib.pyplot as plt
# Download data from open datasets
from download import download
url = "https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/" \
"notebook/datasets/MNIST_Data.zip"
path = download(url, "./", kind="zip", replace=True)
train_dataset = MnistDataset("MNIST_Data/train", shuffle=False)
print(type(train_dataset))
def visualize(dataset):
figure = plt.figure(figsize=(4, 4))
cols, rows = 3, 3
plt.subplots_adjust(wspace=0.5, hspace=0.5)
for idx, (image, label) in enumerate(dataset.create_tuple_iterator()):
figure.add_subplot(rows, cols, idx + 1)
plt.title(int(label))
plt.axis("off")
plt.imshow(image.asnumpy().squeeze(), cmap="gray")
if idx == cols * rows - 1:
break
plt.show()
visualize(train_dataset)
Downloading data from https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/datasets/MNIST_Data.zip (10.3 MB)
file_sizes: 100%|███████████████████████████| 10.8M/10.8M [00:00<00:00, 132MB/s]
Extracting zip file...
Successfully downloaded / unzipped to ./
<class 'mindspore.dataset.engine.datasets_vision.MnistDataset'>
![外链图
train_dataset = train_dataset.shuffle(buffer_size=64)
visualize(train_dataset)
![外
image, label = next(train_dataset.create_tuple_iterator())
print(image.shape, image.dtype)
(28, 28, 1) UInt8
train_dataset = train_dataset.map(vision.Rescale(1.0 / 255.0, 0), input_columns='image')
image, label = next(train_dataset.create_tuple_iterator())
print(image.shape, image.dtype)
(28, 28, 1) Float32
#help(vision.Rescale(1.0 / 255.0, 0))
vision.Rescale是MindSpore库中一个用于图像预处理的变换操作。这个类可以帮助用户调整图像的像素值,通常用于将图像的像素值从原始范围映射到神经网络模型期望的输入范围。下面是对这个方法的详细说明以及一个使用示例。
功能描述
vision.Rescale(rescale, shift)接收两个参数:
rescale:一个浮点数,用于乘以图像中的每一个像素值。例如,如果原始图像的像素值范围是0-255,而你的模型期望的输入范围是0-1,那么你就可以设置rescale=1.0 / 255.0来进行缩放。
shift:一个浮点数,用于在缩放后的像素值上进行偏移。这可以用来进一步调整图像的亮度或其他特性。
公式
应用到每个像素上的计算公式为:output = image * rescale + shift。
举例说明
假设你有一个图像数据集,其中的图像像素值范围为0-255,你想要使用一个神经网络模型进行训练,但这个模型期望的输入图像像素值范围是0-1。这时,你可以使用vision.Rescale来调整图像的像素值范围
# Random-accessible object as input source
class RandomAccessDataset:
def __init__(self):
self._data = np.ones((5, 2))
self._label = np.zeros((5, 1))
def __getitem__(self, index):
return self._data[index], self._label[index]
def __len__(self):
return len(self._data)
loader = RandomAccessDataset()
dataset = GeneratorDataset(source=loader, column_names=["data", "label"])
for data in dataset:
print(data)
[Tensor(shape=[2], dtype=Float64, value= [ 1.00000000e+00, 1.00000000e+00]), Tensor(shape=[1], dtype=Float64, value= [ 0.00000000e+00])]
[Tensor(shape=[2], dtype=Float64, value= [ 1.00000000e+00, 1.00000000e+00]), Tensor(shape=[1], dtype=Float64, value= [ 0.00000000e+00])]
[Tensor(shape=[2], dtype=Float64, value= [ 1.00000000e+00, 1.00000000e+00]), Tensor(shape=[1], dtype=Float64, value= [ 0.00000000e+00])]
[Tensor(shape=[2], dtype=Float64, value= [ 1.00000000e+00, 1.00000000e+00]), Tensor(shape=[1], dtype=Float64, value= [ 0.00000000e+00])]
[Tensor(shape=[2], dtype=Float64, value= [ 1.00000000e+00, 1.00000000e+00]), Tensor(shape=[1], dtype=Float64, value= [ 0.00000000e+00])]
# list, tuple are also supported.
loader = [np.array(0), np.array(1), np.array(2)]
dataset = GeneratorDataset(source=loader, column_names=["data"])
for data in dataset:
print(data)
[Tensor(shape=[], dtype=Int64, value= 0)]
[Tensor(shape=[], dtype=Int64, value= 1)]
[Tensor(shape=[], dtype=Int64, value= 2)]
# Iterator as input source
class IterableDataset():
def __init__(self, start, end):
'''init the class object to hold the data'''
self.start = start
self.end = end
def __next__(self):
'''iter one data and return'''
return next(self.data)
def __iter__(self):
'''reset the iter'''
self.data = iter(range(self.start, self.end))
return self
loader = IterableDataset(1, 5)
dataset = GeneratorDataset(source=loader, column_names=["data"])
for d in dataset:
print(d)
# Generator
def my_generator(start, end):
for i in range(start, end):
yield i
# since a generator instance can be only iterated once, we need to wrap it by lambda to generate multiple instances
dataset = GeneratorDataset(source=lambda: my_generator(3, 6), column_names=["data"])
for d in dataset:
print(d)
[Tensor(shape=[], dtype=Int64, value= 1)]
[Tensor(shape=[], dtype=Int64, value= 2)]
[Tensor(shape=[], dtype=Int64, value= 3)]
[Tensor(shape=[], dtype=Int64, value= 4)]
[Tensor(shape=[], dtype=Int64, value= 3)]
[Tensor(shape=[], dtype=Int64, value= 4)]
[Tensor(shape=[], dtype=Int64, value= 5)]
import numpy as np
from PIL import Image
from download import download
from mindspore.dataset import transforms, vision, text
from mindspore.dataset import GeneratorDataset, MnistDataset
# Download data from open datasets
url = "https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/" \
"notebook/datasets/MNIST_Data.zip"
path = download(url, "./", kind="zip", replace=True)
train_dataset = MnistDataset('MNIST_Data/train')
Downloading data from https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/datasets/MNIST_Data.zip (10.3 MB)
file_sizes: 100%|██████████████████████████| 10.8M/10.8M [00:00<00:00, 99.7MB/s]
Extracting zip file...
Successfully downloaded / unzipped to ./
image, label = next(train_dataset.create_tuple_iterator())
print(image.shape)
(28, 28, 1)
composed = transforms.Compose(
[
vision.Rescale(1.0 / 255.0, 0),
vision.Normalize(mean=(0.1307,), std=(0.3081,)),
vision.HWC2CHW()
]
)
train_dataset = train_dataset.map(composed, 'image')
image, label = next(train_dataset.create_tuple_iterator())
print(image.shape)
random_np = np.random.randint(0, 255, (48, 48), np.uint8)
random_image = Image.fromarray(random_np)
print(random_np)
(1, 28, 28)
[[151 87 208 ... 136 47 16]
[ 39 166 246 ... 226 97 25]
[118 253 158 ... 227 28 177]
...
[169 34 92 ... 57 74 201]
[ 26 177 214 ... 104 235 53]
[ 63 160 42 ... 202 188 69]]
在深度学习图像处理中,Normalize
是一个常见的预处理步骤,用于将图像像素值标准化到一个特定的分布,通常是为了使模型训练更加稳定和高效。在你给出的代码段中,vision.Normalize(mean=(0.1307,), std=(0.3081,))
是Compose
函数中的一部分,用于构建一个图像预处理管道。下面是对这个Normalize
操作的详细解析和举例说明。
Normalize操作解析
Normalize
函数的主要作用是将图像的每个通道的像素值减去平均值(mean)并除以标准差(std),从而使得数据具有零均值和单位方差,或者说是符合标准正态分布。这对于很多机器学习和深度学习算法是非常有益的,因为它可以减少不同特征尺度差异的影响,加速模型收敛。
具体到你给出的例子:
-
mean=(0.1307,)
: 这意味着在预处理过程中,会从图像每个像素值中减去0.1307。这里只有一个值,说明是在处理灰度图像或者对所有颜色通道统一应用相同的均值(在处理RGB图像时,mean通常是一个包含R、G、B三个通道均值的元组,比如(0.485, 0.456, 0.406)
)。 -
std=(0.3081,)
: 同样,标准差为0.3081,表示每个像素值还会除以这个值。这同样适用于所有通道,如果是彩色图像处理,通常std也会是三个通道的标准差组成的元组。
举例说明
假设你有一幅灰度图像,某像素点的原始灰度值为100(在0-255的范围内):
-
Rescale操作首先会将这个值转换到0-1的范围:
[100 \times \frac{1}{255} = 0.3921] -
接着,Normalize操作会进一步调整这个值:
- 减去均值:[0.3921 - 0.1307 = 0.2614]
- 除以标准差:[0.2614 / 0.3081 ≈ 0.8488]
因此,经过Rescale
和Normalize
预处理后,原始像素值100最终被转换为了大约0.8488。这个标准化过程确保了图像数据在送入神经网络之前具有统一的尺度,有助于优化模型的学习过程。
实际应用
在实际应用中,mean
和std
的值通常基于训练数据集统计得出,以反映数据集的整体分布情况。例如,在使用MNIST、CIFAR-10这类标准数据集时,会有推荐的归一化参数。而在自定义数据集上,你可能需要自己计算这些统计量。
rescale = vision.Rescale(1.0 / 255.0, 0)
rescaled_image = rescale(random_image)
print(rescaled_image)
[[0.5921569 0.34117648 0.81568635 ... 0.53333336 0.18431373 0.0627451 ]
[0.15294118 0.6509804 0.96470594 ... 0.8862746 0.3803922 0.09803922]
[0.46274513 0.9921569 0.61960787 ... 0.89019614 0.10980393 0.69411767]
...
[0.6627451 0.13333334 0.36078432 ... 0.22352943 0.2901961 0.78823537]
[0.10196079 0.69411767 0.83921576 ... 0.40784317 0.9215687 0.20784315]
[0.24705884 0.627451 0.16470589 ... 0.79215693 0.7372549 0.27058825]]
normalize = vision.Normalize(mean=(0.1307,), std=(0.3081,))
normalized_image = normalize(rescaled_image)
print(normalized_image)
hwc_image = np.expand_dims(normalized_image, -1)
hwc2chw = vision.HWC2CHW()
chw_image = hwc2chw(hwc_image)
print(hwc_image.shape, chw_image.shape)
[[ 1.4977505 0.6831434 2.22326 ... 1.306827 0.17401403
-0.2205612 ]
[ 0.07218818 1.688674 2.7069328 ... 2.452368 0.8104258
-0.10600709]
[ 1.0777187 2.7960305 1.5868481 ... 2.4650965 -0.06782239
1.8286846 ]
...
[ 1.7268586 0.00854701 0.74678457 ... 0.3012964 0.51767635
2.1341622 ]
[-0.09327886 1.8286846 2.2996294 ... 0.8995235 2.5669222
0.2503835 ]
[ 0.37766582 1.6123046 0.11037287 ... 2.1468906 1.968695
0.45403522]]
(48, 48, 1) (1, 48, 48)
texts = ['Welcome to Beijing yes i do']
test_dataset = GeneratorDataset(texts, 'text')
def my_tokenizer(content):
return content.split()
test_dataset = test_dataset.map(text.PythonTokenizer(my_tokenizer))
print(next(test_dataset.create_tuple_iterator()))
[Tensor(shape=[6], dtype=String, value= ['Welcome', 'to', 'Beijing', 'yes', 'i', 'do'])]
vocab = text.Vocab.from_dataset(test_dataset)
vocab
<mindspore.dataset.text.utils.Vocab at 0xfffe1c7b1a60>
print(vocab.vocab())
{'yes': 5, 'to': 4, 'do': 2, 'i': 3, 'Welcome': 1, 'Beijing': 0}
生成词表后,可以配合map方法进行词表映射变换,将Token转为Index。
test_dataset = test_dataset.map(text.Lookup(vocab))
print(next(test_dataset.create_tuple_iterator()))
[Tensor(shape=[6], dtype=Int32, value= [1, 4, 0, 5, 3, 2])]
test_dataset = GeneratorDataset([1, 2, 3], 'data', shuffle=False)
test_dataset = test_dataset.map(lambda x: x * 2)
print(list(test_dataset.create_tuple_iterator()))
[[Tensor(shape=[], dtype=Int64, value= 2)], [Tensor(shape=[], dtype=Int64, value= 4)], [Tensor(shape=[], dtype=Int64, value= 6)]]
def func(x):
return x * x + 2
test_dataset = test_dataset.map(lambda x: func(x))
print("wancheng author:yangge yyp 2024-6-20")
wancheng author:yangge yyp 2024-6-20
import numpy as np
import mindspore
from mindspore import ops
from mindspore import Tensor, CSRTensor, COOTensor
data = [1, 0, 1, 0]
x_data = Tensor(data)
print(x_data, x_data.shape, x_data.dtype)
np_array = np.array(data)
x_np = Tensor(np_array)
print(x_np, x_np.shape, x_np.dtype)
from mindspore.common.initializer import One, Normal
# Initialize a tensor with ones
tensor1 = mindspore.Tensor(shape=(2, 2), dtype=mindspore.float32, init=One())
# Initialize a tensor from normal distribution
tensor2 = mindspore.Tensor(shape=(2, 2), dtype=mindspore.float32, init=Normal())
print("tensor1:\n", tensor1)
print("tensor2:\n", tensor2)
from mindspore import ops
x_ones = ops.ones_like(x_data)
print(f"Ones Tensor: \n {x_ones} \n")
x_zeros = ops.zeros_like(x_data)
print(f"Zeros Tensor: \n {x_zeros} \n")
[1 0 1 0] (4,) Int64
[1 0 1 0] (4,) Int64
tensor1:
[[1. 1.]
[1. 1.]]
tensor2:
[[ 0.01097696 0.01645728]
[-0.00532449 -0.00663322]]
Ones Tensor:
[1 1 1 1]
Zeros Tensor:
[0 0 0 0]
x = Tensor(np.array([[1, 2], [3, 4]]), mindspore.int32)
print("x_shape:", x.shape)
print("x_dtype:", x.dtype)
print("x_itemsize:", x.itemsize)
print("x_nbytes:", x.nbytes)
print("x_ndim:", x.ndim)
print("x_size:", x.size)
print("x_strides:", x.strides)
x_shape: (2, 2)
x_dtype: Int32
x_itemsize: 4
x_nbytes: 16
x_ndim: 2
x_size: 4
x_strides: (8, 4)
tensor = Tensor(np.array([[0, 1], [2, 3]]).astype(np.float32))
print("First row: {}".format(tensor[0]))
print("value of bottom right corner: {}".format(tensor[1, 1]))
print("Last column: {}".format(tensor[:, -1]))
print("First column: {}".format(tensor[..., 0]))
First row: [0. 1.]
value of bottom right corner: 3.0
Last column: [1. 3.]
First column: [0. 2.]
x = Tensor(np.array([1, 2, 3]), mindspore.float32)
y = Tensor(np.array([4, 5, 6]), mindspore.float32)
output_add = x + y
output_sub = x - y
output_mul = x * y
output_div = y / x
output_mod = y % x
output_floordiv = y // x
print("add:", output_add)
print("sub:", output_sub)
print("mul:", output_mul)
print("div:", output_div)
print("mod:", output_mod)
print("floordiv:", output_floordiv)
data1 = Tensor(np.array([[0, 1], [2, 3]]).astype(np.float32))
data2 = Tensor(np.array([[4, 5], [6, 7]]).astype(np.float32))
output = ops.concat((data1, data2), axis=0)
print(output)
print("shape:\n", output.shape)
add: [5. 7. 9.]
sub: [-3. -3. -3.]
mul: [ 4. 10. 18.]
div: [4. 2.5 2. ]
mod: [0. 1. 0.]
floordiv: [4. 2. 2.]
[[0. 1.]
[2. 3.]
[4. 5.]
[6. 7.]]
shape:
(4, 2)
data1 = Tensor(np.array([[0, 1], [2, 3]]).astype(np.float32))
data2 = Tensor(np.array([[4, 5], [6, 7]]).astype(np.float32))
output = ops.stack([data1, data2])
print(output)
print("shape:\n", output.shape)
t = Tensor([1., 1., 1., 1., 1.])
print(f"t: {t}", type(t))
n = t.asnumpy()
print(f"n: {n}", type(n))
n = np.ones(5)
t = Tensor.from_numpy(n)
np.add(n, 1, out=n)
print(f"n: {n}", type(n))
print(f"t: {t}", type(t))
[[[0. 1.]
[2. 3.]]
[[4. 5.]
[6. 7.]]]
shape:
(2, 2, 2)
t: [1. 1. 1. 1. 1.] <class 'mindspore.common.tensor.Tensor'>
n: [1. 1. 1. 1. 1.] <class 'numpy.ndarray'>
n: [2. 2. 2. 2. 2.] <class 'numpy.ndarray'>
t: [2. 2. 2. 2. 2.] <class 'mindspore.common.tensor.Tensor'>
indptr = Tensor([0, 1, 2])
indices = Tensor([0, 1])
values = Tensor([1, 2], dtype=mindspore.float32)
shape = (2, 4)
# Make a CSRTensor
csr_tensor = CSRTensor(indptr, indices, values, shape)
print(csr_tensor.astype(mindspore.float64).dtype)
Float64
上述代码会生成如下所示的CSRTensor
:
[ 1 0 0 0 0 2 0 0 ] \left[ \begin{matrix} 1 & 0 & 0 & 0 \\ 0 & 2 & 0 & 0 \end{matrix} \right] [10020000]
这段代码展示了如何在MindSpore框架中使用稀疏矩阵表示法中的CSR(Compressed Sparse Row)格式来创建一个稀疏张量,并进一步将其数据类型转换为mindspore.float64
。下面是对代码的逐步解析:
数据结构介绍
在稀疏矩阵表示中,CSR格式是一种常用的方式,特别适合于行稀疏的矩阵。它由三个数组组成:
- indptr (indices pointer): 一个一维数组,表示每行开始的索引位置。最后一个元素通常表示超过最后一行的偏移量,从而间接给出矩阵的行数。
- indices: 一个一维数组,表示非零元素对应的列索引。
- values: 一个一维数组,存储了矩阵中的非零元素值,与
indices
一一对应。 - shape: 一个元组,表示矩阵的维度。
代码解析
- indptr = Tensor([0, 1, 2]): 表示有两行数据,第一行的非零元素从位置0开始,第二行的非零元素从位置1开始。由于没有第三个值,可以推断只有两行。
- indices = Tensor([0, 1]): 表示非零元素分别位于第0列和第1列。
- values = Tensor([1, 2], dtype=mindspore.float32): 存储非零元素的值,分别为1和2,且指定数据类型为32位浮点数。
- shape = (2, 4): 矩阵为2行4列。
创建CSRTensor
通过CSRTensor(indptr, indices, values, shape)
构造函数,将上述信息组合成一个CSRTensor对象,表示一个2x4的稀疏矩阵,其中有效元素为(0,0)=1和(1,1)=2。
数据类型转换
csr_tensor.astype(mindspore.float64)
这一行代码的作用是将csr_tensor
的数据类型转换为64位浮点数(mindspore.float64
)。.astype()
是MindSpore中用于改变Tensor数据类型的方法。
打印结果
print(csr_tensor.astype(mindspore.float64).dtype)
会输出转换后的数据类型,即mindspore.float64
,表明转换成功。
位置查找
至于“怎么找到位置”,在稀疏矩阵的CSR表示中,给定一个元素值,要找到它的位置(行和列索引),可以通过以下步骤:
- 确定行: 查找
indptr
来确定元素所在的行。具体来说,找到满足indptr[i] <= element_index < indptr[i+1]
的第一个i
,则元素位于第i
行。 - 确定列: 在
indices
数组中,元素的索引(相对于values
)指向其所在的列。即,如果元素在values
中的索引是j
,那么它位于第indices[j]
列。
例如,如果想找到值为2的位置,我们知道它在values
中的索引是1,因此它位于indices[1]
所指的列,即第1列;又因为它在values
中的第一个元素之后,根据indptr
,它属于第二行。因此,值2位于(1,1)的位置。
indices = Tensor([[0, 1], [1, 2]], dtype=mindspore.int32)
values = Tensor([1, 2], dtype=mindspore.float32)
shape = (3, 4)
# Make a COOTensor
coo_tensor = COOTensor(indices, values, shape)
print(coo_tensor.values)
print(coo_tensor.indices)
print(coo_tensor.shape)
print(coo_tensor.astype(mindspore.float64).dtype) # COOTensor to float64
[1. 2.]
[[0 1]
[1 2]]
(3, 4)
Float64
这段代码展示了在MindSpore框架中如何使用另一种稀疏矩阵表示法COO(Coordinate Format,坐标格式)来创建一个稀疏张量,并展示了如何访问其属性以及转换数据类型。下面是详细的解析:
COO格式简介
COO(Coordinate Format)格式是稀疏矩阵的一种存储方式,它直接存储非零元素的坐标(行索引和列索引)及对应的值。这种格式通过三个主要部分来表示稀疏矩阵:
- indices: 一个二维张量,每一行表示一个非零元素的行索引和列索引。
- values: 一个一维张量,存储了与
indices
中索引对应的非零元素的值。 - shape: 一个元组,表示稀疏矩阵的形状(行数和列数)。
代码解析
- indices = Tensor([[0, 1], [1, 2]], dtype=mindspore.int32): 表示有两个非零元素,它们的坐标分别是(0, 1)和(1, 2)。
- values = Tensor([1, 2], dtype=mindspore.float32): 这些坐标上的元素值分别是1和2。
- shape = (3, 4): 定义了稀疏矩阵的维度为3行4列。
创建COOTensor
通过COOTensor(indices, values, shape)
,利用给定的索引、值和形状创建了一个COO格式的稀疏张量。
访问属性
- coo_tensor.values: 输出非零元素的值,即
[1, 2]
。 - coo_tensor.indices: 输出非零元素的坐标,即
[[0, 1], [1, 2]]
。 - coo_tensor.shape: 输出稀疏矩阵的形状,即
(3, 4)
。
数据类型转换
coo_tensor.astype(mindspore.float64).dtype
: 将COOTensor的数据类型转换为64位浮点数,并打印转换后的数据类型,输出应为mindspore.float64
。
如何找到位置
在COO格式中,每个非零元素的位置(行和列)直接存储在indices
中:
- 查找元素位置: 假设要查找值为2的位置,首先在
values
中找到该值,它位于第1个位置。然后,在indices
的相应位置(即第1行)查看索引,得到[1, 2]
。这表示值2位于第1行第2列。
因此,对于COO张量,直接通过indices
属性就能快速获取到每个非零元素的确切位置(行号和列号)。
上述代码会生成如下所示的COOTensor
:
[ 0 1 0 0 0 0 2 0 0 0 0 0 ] \left[ \begin{matrix} 0 & 1 & 0 & 0 \\ 0 & 0 & 2 & 0 \\ 0 & 0 & 0 & 0 \end{matrix} \right] 000100020000
import numpy as np
from mindspore.dataset import vision
from mindspore.dataset import MnistDataset, GeneratorDataset
import matplotlib.pyplot as plt
# Download data from open datasets
from download import download
url = "https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/" \
"notebook/datasets/MNIST_Data.zip"
path = download(url, "./", kind="zip", replace=True)
train_dataset = MnistDataset("MNIST_Data/train", shuffle=False)
print(type(train_dataset))
def visualize(dataset):
figure = plt.figure(figsize=(4, 4))
cols, rows = 3, 3
plt.subplots_adjust(wspace=0.5, hspace=0.5)
for idx, (image, label) in enumerate(dataset.create_tuple_iterator()):
figure.add_subplot(rows, cols, idx + 1)
plt.title(int(label))
plt.axis("off")
plt.imshow(image.asnumpy().squeeze(), cmap="gray")
if idx == cols * rows - 1:
break
plt.show()
visualize(train_dataset)
Downloading data from https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/datasets/MNIST_Data.zip (10.3 MB)
file_sizes: 100%|███████████████████████████| 10.8M/10.8M [00:00<00:00, 132MB/s]
Extracting zip file...
Successfully downloaded / unzipped to ./
<class 'mindspore.dataset.engine.datasets_vision.MnistDataset'>
train_dataset = train_dataset.shuffle(buffer_size=64)
visualize(train_dataset)
image, label = next(train_dataset.create_tuple_iterator())
print(image.shape, image.dtype)
(28, 28, 1) UInt8
train_dataset = train_dataset.map(vision.Rescale(1.0 / 255.0, 0), input_columns='image')
image, label = next(train_dataset.create_tuple_iterator())
print(image.shape, image.dtype)
(28, 28, 1) Float32
#help(vision.Rescale(1.0 / 255.0, 0))
vision.Rescale是MindSpore库中一个用于图像预处理的变换操作。这个类可以帮助用户调整图像的像素值,通常用于将图像的像素值从原始范围映射到神经网络模型期望的输入范围。下面是对这个方法的详细说明以及一个使用示例。
功能描述
vision.Rescale(rescale, shift)接收两个参数:
rescale:一个浮点数,用于乘以图像中的每一个像素值。例如,如果原始图像的像素值范围是0-255,而你的模型期望的输入范围是0-1,那么你就可以设置rescale=1.0 / 255.0来进行缩放。
shift:一个浮点数,用于在缩放后的像素值上进行偏移。这可以用来进一步调整图像的亮度或其他特性。
公式
应用到每个像素上的计算公式为:output = image * rescale + shift。
举例说明
假设你有一个图像数据集,其中的图像像素值范围为0-255,你想要使用一个神经网络模型进行训练,但这个模型期望的输入图像像素值范围是0-1。这时,你可以使用vision.Rescale来调整图像的像素值范围
# Random-accessible object as input source
class RandomAccessDataset:
def __init__(self):
self._data = np.ones((5, 2))
self._label = np.zeros((5, 1))
def __getitem__(self, index):
return self._data[index], self._label[index]
def __len__(self):
return len(self._data)
loader = RandomAccessDataset()
dataset = GeneratorDataset(source=loader, column_names=["data", "label"])
for data in dataset:
print(data)
[Tensor(shape=[2], dtype=Float64, value= [ 1.00000000e+00, 1.00000000e+00]), Tensor(shape=[1], dtype=Float64, value= [ 0.00000000e+00])]
[Tensor(shape=[2], dtype=Float64, value= [ 1.00000000e+00, 1.00000000e+00]), Tensor(shape=[1], dtype=Float64, value= [ 0.00000000e+00])]
[Tensor(shape=[2], dtype=Float64, value= [ 1.00000000e+00, 1.00000000e+00]), Tensor(shape=[1], dtype=Float64, value= [ 0.00000000e+00])]
[Tensor(shape=[2], dtype=Float64, value= [ 1.00000000e+00, 1.00000000e+00]), Tensor(shape=[1], dtype=Float64, value= [ 0.00000000e+00])]
[Tensor(shape=[2], dtype=Float64, value= [ 1.00000000e+00, 1.00000000e+00]), Tensor(shape=[1], dtype=Float64, value= [ 0.00000000e+00])]
# list, tuple are also supported.
loader = [np.array(0), np.array(1), np.array(2)]
dataset = GeneratorDataset(source=loader, column_names=["data"])
for data in dataset:
print(data)
[Tensor(shape=[], dtype=Int64, value= 0)]
[Tensor(shape=[], dtype=Int64, value= 1)]
[Tensor(shape=[], dtype=Int64, value= 2)]
# Iterator as input source
class IterableDataset():
def __init__(self, start, end):
'''init the class object to hold the data'''
self.start = start
self.end = end
def __next__(self):
'''iter one data and return'''
return next(self.data)
def __iter__(self):
'''reset the iter'''
self.data = iter(range(self.start, self.end))
return self
loader = IterableDataset(1, 5)
dataset = GeneratorDataset(source=loader, column_names=["data"])
for d in dataset:
print(d)
# Generator
def my_generator(start, end):
for i in range(start, end):
yield i
# since a generator instance can be only iterated once, we need to wrap it by lambda to generate multiple instances
dataset = GeneratorDataset(source=lambda: my_generator(3, 6), column_names=["data"])
for d in dataset:
print(d)
[Tensor(shape=[], dtype=Int64, value= 1)]
[Tensor(shape=[], dtype=Int64, value= 2)]
[Tensor(shape=[], dtype=Int64, value= 3)]
[Tensor(shape=[], dtype=Int64, value= 4)]
[Tensor(shape=[], dtype=Int64, value= 3)]
[Tensor(shape=[], dtype=Int64, value= 4)]
[Tensor(shape=[], dtype=Int64, value= 5)]
import numpy as np
from PIL import Image
from download import download
from mindspore.dataset import transforms, vision, text
from mindspore.dataset import GeneratorDataset, MnistDataset
# Download data from open datasets
url = "https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/" \
"notebook/datasets/MNIST_Data.zip"
path = download(url, "./", kind="zip", replace=True)
train_dataset = MnistDataset('MNIST_Data/train')
Downloading data from https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/datasets/MNIST_Data.zip (10.3 MB)
file_sizes: 100%|██████████████████████████| 10.8M/10.8M [00:00<00:00, 99.7MB/s]
Extracting zip file...
Successfully downloaded / unzipped to ./
image, label = next(train_dataset.create_tuple_iterator())
print(image.shape)
(28, 28, 1)
composed = transforms.Compose(
[
vision.Rescale(1.0 / 255.0, 0),
vision.Normalize(mean=(0.1307,), std=(0.3081,)),
vision.HWC2CHW()
]
)
train_dataset = train_dataset.map(composed, 'image')
image, label = next(train_dataset.create_tuple_iterator())
print(image.shape)
random_np = np.random.randint(0, 255, (48, 48), np.uint8)
random_image = Image.fromarray(random_np)
print(random_np)
(1, 28, 28)
[[151 87 208 ... 136 47 16]
[ 39 166 246 ... 226 97 25]
[118 253 158 ... 227 28 177]
...
[169 34 92 ... 57 74 201]
[ 26 177 214 ... 104 235 53]
[ 63 160 42 ... 202 188 69]]
在深度学习图像处理中,Normalize
是一个常见的预处理步骤,用于将图像像素值标准化到一个特定的分布,通常是为了使模型训练更加稳定和高效。在你给出的代码段中,vision.Normalize(mean=(0.1307,), std=(0.3081,))
是Compose
函数中的一部分,用于构建一个图像预处理管道。下面是对这个Normalize
操作的详细解析和举例说明。
Normalize操作解析
Normalize
函数的主要作用是将图像的每个通道的像素值减去平均值(mean)并除以标准差(std),从而使得数据具有零均值和单位方差,或者说是符合标准正态分布。这对于很多机器学习和深度学习算法是非常有益的,因为它可以减少不同特征尺度差异的影响,加速模型收敛。
具体到你给出的例子:
-
mean=(0.1307,)
: 这意味着在预处理过程中,会从图像每个像素值中减去0.1307。这里只有一个值,说明是在处理灰度图像或者对所有颜色通道统一应用相同的均值(在处理RGB图像时,mean通常是一个包含R、G、B三个通道均值的元组,比如(0.485, 0.456, 0.406)
)。 -
std=(0.3081,)
: 同样,标准差为0.3081,表示每个像素值还会除以这个值。这同样适用于所有通道,如果是彩色图像处理,通常std也会是三个通道的标准差组成的元组。
举例说明
假设你有一幅灰度图像,某像素点的原始灰度值为100(在0-255的范围内):
-
Rescale操作首先会将这个值转换到0-1的范围:
[100 \times \frac{1}{255} = 0.3921] -
接着,Normalize操作会进一步调整这个值:
- 减去均值:[0.3921 - 0.1307 = 0.2614]
- 除以标准差:[0.2614 / 0.3081 ≈ 0.8488]
因此,经过Rescale
和Normalize
预处理后,原始像素值100最终被转换为了大约0.8488。这个标准化过程确保了图像数据在送入神经网络之前具有统一的尺度,有助于优化模型的学习过程。
实际应用
在实际应用中,mean
和std
的值通常基于训练数据集统计得出,以反映数据集的整体分布情况。例如,在使用MNIST、CIFAR-10这类标准数据集时,会有推荐的归一化参数。而在自定义数据集上,你可能需要自己计算这些统计量。
rescale = vision.Rescale(1.0 / 255.0, 0)
rescaled_image = rescale(random_image)
print(rescaled_image)
[[0.5921569 0.34117648 0.81568635 ... 0.53333336 0.18431373 0.0627451 ]
[0.15294118 0.6509804 0.96470594 ... 0.8862746 0.3803922 0.09803922]
[0.46274513 0.9921569 0.61960787 ... 0.89019614 0.10980393 0.69411767]
...
[0.6627451 0.13333334 0.36078432 ... 0.22352943 0.2901961 0.78823537]
[0.10196079 0.69411767 0.83921576 ... 0.40784317 0.9215687 0.20784315]
[0.24705884 0.627451 0.16470589 ... 0.79215693 0.7372549 0.27058825]]
normalize = vision.Normalize(mean=(0.1307,), std=(0.3081,))
normalized_image = normalize(rescaled_image)
print(normalized_image)
hwc_image = np.expand_dims(normalized_image, -1)
hwc2chw = vision.HWC2CHW()
chw_image = hwc2chw(hwc_image)
print(hwc_image.shape, chw_image.shape)
[[ 1.4977505 0.6831434 2.22326 ... 1.306827 0.17401403
-0.2205612 ]
[ 0.07218818 1.688674 2.7069328 ... 2.452368 0.8104258
-0.10600709]
[ 1.0777187 2.7960305 1.5868481 ... 2.4650965 -0.06782239
1.8286846 ]
...
[ 1.7268586 0.00854701 0.74678457 ... 0.3012964 0.51767635
2.1341622 ]
[-0.09327886 1.8286846 2.2996294 ... 0.8995235 2.5669222
0.2503835 ]
[ 0.37766582 1.6123046 0.11037287 ... 2.1468906 1.968695
0.45403522]]
(48, 48, 1) (1, 48, 48)
texts = ['Welcome to Beijing yes i do']
test_dataset = GeneratorDataset(texts, 'text')
def my_tokenizer(content):
return content.split()
test_dataset = test_dataset.map(text.PythonTokenizer(my_tokenizer))
print(next(test_dataset.create_tuple_iterator()))
[Tensor(shape=[6], dtype=String, value= ['Welcome', 'to', 'Beijing', 'yes', 'i', 'do'])]
vocab = text.Vocab.from_dataset(test_dataset)
vocab
<mindspore.dataset.text.utils.Vocab at 0xfffe1c7b1a60>
print(vocab.vocab())
{'yes': 5, 'to': 4, 'do': 2, 'i': 3, 'Welcome': 1, 'Beijing': 0}
生成词表后,可以配合map方法进行词表映射变换,将Token转为Index。
test_dataset = test_dataset.map(text.Lookup(vocab))
print(next(test_dataset.create_tuple_iterator()))
[Tensor(shape=[6], dtype=Int32, value= [1, 4, 0, 5, 3, 2])]
test_dataset = GeneratorDataset([1, 2, 3], 'data', shuffle=False)
test_dataset = test_dataset.map(lambda x: x * 2)
print(list(test_dataset.create_tuple_iterator()))
[[Tensor(shape=[], dtype=Int64, value= 2)], [Tensor(shape=[], dtype=Int64, value= 4)], [Tensor(shape=[], dtype=Int64, value= 6)]]
def func(x):
return x * x + 2
test_dataset = test_dataset.map(lambda x: func(x))
print("wancheng author:yangge yyp 2024-6-20")
wancheng author:yangge yyp 2024-6-20