nodev 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nodev-1.0.0/PKG-INFO +13 -0
- nodev-1.0.0/README.md +0 -0
- nodev-1.0.0/pyproject.toml +26 -0
- nodev-1.0.0/setup.cfg +4 -0
- nodev-1.0.0/src/__init__.py +0 -0
- nodev-1.0.0/src/nodev/__init__.py +18 -0
- nodev-1.0.0/src/nodev/core.py +297 -0
- nodev-1.0.0/src/nodev/cuda.py +27 -0
- nodev-1.0.0/src/nodev/dataloaders.py +65 -0
- nodev-1.0.0/src/nodev/dataset.py +186 -0
- nodev-1.0.0/src/nodev/layers.py +179 -0
- nodev-1.0.0/src/nodev/model.py +119 -0
- nodev-1.0.0/src/nodev/operations.py +389 -0
- nodev-1.0.0/src/nodev/operations_conv.py +474 -0
- nodev-1.0.0/src/nodev/optimizer.py +72 -0
- nodev-1.0.0/src/nodev/transforms.py +65 -0
- nodev-1.0.0/src/nodev/utils.py +172 -0
- nodev-1.0.0/src/nodev.egg-info/PKG-INFO +13 -0
- nodev-1.0.0/src/nodev.egg-info/SOURCES.txt +20 -0
- nodev-1.0.0/src/nodev.egg-info/dependency_links.txt +1 -0
- nodev-1.0.0/src/nodev.egg-info/requires.txt +2 -0
- nodev-1.0.0/src/nodev.egg-info/top_level.txt +2 -0
nodev-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: nodev
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: 一个轻量级深度学习第三方库,2026年设计。
|
|
5
|
+
Author-email: Yang Yaqing <youngtoothh@foxmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
+
Classifier: Operating System :: OS Independent
|
|
10
|
+
Requires-Python: >=3.8
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
Requires-Dist: requests>=2.28.0
|
|
13
|
+
Requires-Dist: numpy
|
nodev-1.0.0/README.md
ADDED
|
File without changes
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
# 重要:这个名字必须独一无二,不能和 PyPI 上已存在的重名
|
|
7
|
+
name = "nodev"
|
|
8
|
+
version = "1.0.0"
|
|
9
|
+
authors = [
|
|
10
|
+
{ name="Yang Yaqing", email="youngtoothh@foxmail.com" },
|
|
11
|
+
]
|
|
12
|
+
description = "一个轻量级深度学习第三方库,2026年设计。"
|
|
13
|
+
readme = "README.md"
|
|
14
|
+
requires-python = ">=3.8"
|
|
15
|
+
license = { text="MIT" } # 或 "Apache-2.0" 等
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"License :: OSI Approved :: MIT License",
|
|
19
|
+
"Operating System :: OS Independent",
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
# 在这里列出你的项目依赖
|
|
23
|
+
dependencies = [
|
|
24
|
+
"requests>=2.28.0",
|
|
25
|
+
"numpy",
|
|
26
|
+
]
|
nodev-1.0.0/setup.cfg
ADDED
|
File without changes
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from nodev.core import Datafield
|
|
2
|
+
from nodev.core import Operation
|
|
3
|
+
from nodev.core import using_config
|
|
4
|
+
from nodev.core import no_grad
|
|
5
|
+
from nodev.core import as_array
|
|
6
|
+
from nodev.core import as_datafield
|
|
7
|
+
from nodev.core import setup_datafield
|
|
8
|
+
from nodev import operations,operations_conv
|
|
9
|
+
from nodev.core import Formpara
|
|
10
|
+
from nodev.layers import Layer
|
|
11
|
+
from nodev.layers import Linear
|
|
12
|
+
from nodev.model import Model
|
|
13
|
+
from nodev.dataloaders import Dataloader
|
|
14
|
+
from nodev.core import test_mode
|
|
15
|
+
from nodev.core import Config
|
|
16
|
+
from nodev import cuda
|
|
17
|
+
from nodev import dataset
|
|
18
|
+
setup_datafield()
|
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
import weakref
|
|
5
|
+
from contextlib import contextmanager
|
|
6
|
+
|
|
7
|
+
import nodev
|
|
8
|
+
|
|
9
|
+
try:
|
|
10
|
+
import cupy
|
|
11
|
+
array_types=(np.ndarray,cupy.ndarray)
|
|
12
|
+
except ImportError:
|
|
13
|
+
array_types=(np.ndarray)
|
|
14
|
+
class Config:
|
|
15
|
+
enable_backprop=True
|
|
16
|
+
train=True
|
|
17
|
+
|
|
18
|
+
class Datafield:
|
|
19
|
+
__array_priority__=200
|
|
20
|
+
def __init__(self,data,name=None):
|
|
21
|
+
if data is not None:
|
|
22
|
+
if not isinstance(data, np.ndarray): #是判断 “x 是否属于类型 T”
|
|
23
|
+
raise TypeError('{} is not supported'.format(type(data)))
|
|
24
|
+
self.data=data
|
|
25
|
+
self.grad=None
|
|
26
|
+
self.name=name
|
|
27
|
+
self.creator=None
|
|
28
|
+
self.generation=0
|
|
29
|
+
def __sub__(self,other):
|
|
30
|
+
return sub(self,other)
|
|
31
|
+
def __neg__(self):
|
|
32
|
+
return neg(self)
|
|
33
|
+
def __mul__(self,other):
|
|
34
|
+
return mul(self,other)
|
|
35
|
+
def __repr__(self):
|
|
36
|
+
if self.data is None:
|
|
37
|
+
return 'Datafield(None)'
|
|
38
|
+
p=str(self.data).replace('\n','\n'+' '*9)
|
|
39
|
+
return 'Datafield(' + p +')'
|
|
40
|
+
def __truediv__(self, other):
|
|
41
|
+
return div(self,other)
|
|
42
|
+
def __rtruediv__(self, other):
|
|
43
|
+
return rdiv(self,other)
|
|
44
|
+
def __len__(self): return len(self.data)
|
|
45
|
+
def __add__(self,other):
|
|
46
|
+
return add(self,other)
|
|
47
|
+
def __rmul__(self,other):
|
|
48
|
+
return mul(other,self)
|
|
49
|
+
|
|
50
|
+
def __radd__(self,other):
|
|
51
|
+
return add(other, self)
|
|
52
|
+
def __pow__(self, power, modulo=None):
|
|
53
|
+
return pow(self,power)
|
|
54
|
+
def __getitem__(self, slices):
|
|
55
|
+
return nodev.operations.get_item(self, slices)
|
|
56
|
+
|
|
57
|
+
def max(self, axis=None, keepdims=False):
|
|
58
|
+
"""返回最大值"""
|
|
59
|
+
return nodev.operations.max(self, axis, keepdims)
|
|
60
|
+
|
|
61
|
+
def min(self, axis=None, keepdims=False):
|
|
62
|
+
"""返回最小值"""
|
|
63
|
+
return nodev.operations.min(self, axis, keepdims)
|
|
64
|
+
def reshape(self,*shape):
|
|
65
|
+
if len(shape)==1 and isinstance(shape[0],(tuple,list)):
|
|
66
|
+
shape=shape[0]
|
|
67
|
+
return nodev.operations.reshape(self,shape)
|
|
68
|
+
def transpose(self):
|
|
69
|
+
return nodev.operations.transpose(self)
|
|
70
|
+
@property
|
|
71
|
+
def T(self):
|
|
72
|
+
return nodev.operations.transpose(self)
|
|
73
|
+
@property
|
|
74
|
+
def size(self):
|
|
75
|
+
return self.data.size
|
|
76
|
+
def unchain(self):
|
|
77
|
+
self.creator=None
|
|
78
|
+
@property
|
|
79
|
+
def ndim(self):
|
|
80
|
+
return self.data.ndim
|
|
81
|
+
@property
|
|
82
|
+
def shape(self): #取出shape
|
|
83
|
+
return self.data.shape
|
|
84
|
+
@property
|
|
85
|
+
def dtype(self):
|
|
86
|
+
return self.data.dtype
|
|
87
|
+
def clear_grad(self):
|
|
88
|
+
self.grad=None
|
|
89
|
+
def to_cpu(self):
|
|
90
|
+
if self.data is not None:
|
|
91
|
+
self.data=nodev.cuda.as_numpy(self.data)
|
|
92
|
+
def to_gpu(self):
|
|
93
|
+
if self.data is not None:
|
|
94
|
+
self.data=nodev.cuda.as_cupy(self.data)
|
|
95
|
+
def set_creator(self,func):
|
|
96
|
+
self.creator=func #储存当前节点的上一个节点??
|
|
97
|
+
self.generation=func.generation+1
|
|
98
|
+
|
|
99
|
+
def sum(self, axis=None, keepdims=False):
|
|
100
|
+
return nodev.operations.sum(self, axis, keepdims)
|
|
101
|
+
def backward(self, retain_grad=False, create_graph=False):
|
|
102
|
+
if self.grad is None:
|
|
103
|
+
xp=nodev.cuda.get_array_module(self.data)
|
|
104
|
+
self.grad=Datafield(xp.ones_like(self.data)) #创建一个全 1 张量,形状和 data 一样
|
|
105
|
+
#self.grad=Datafield(np.ones_like(self.data))
|
|
106
|
+
funcs=[]
|
|
107
|
+
seen_set=set()
|
|
108
|
+
def add_func(f): #寻找层数最大的因子进行求导
|
|
109
|
+
if f not in seen_set:
|
|
110
|
+
funcs.append(f)
|
|
111
|
+
seen_set.add(f)
|
|
112
|
+
funcs.sort(key=lambda x:x.generation)
|
|
113
|
+
if self.creator is not None:
|
|
114
|
+
add_func(self.creator)
|
|
115
|
+
while funcs:
|
|
116
|
+
f=funcs.pop() #压出最后一个元素
|
|
117
|
+
gys=[output().grad for output in f.outputs] #汇总导数
|
|
118
|
+
#gys = [output.grad for output in f.outputs] # 汇总导数
|
|
119
|
+
with using_config('enable_backprop',create_graph):
|
|
120
|
+
gxs=f.backward(*gys)
|
|
121
|
+
if not isinstance(gxs,tuple):
|
|
122
|
+
gxs=(gxs,)
|
|
123
|
+
for x,gx in zip(f.inputs,gxs):
|
|
124
|
+
if x.grad is None:
|
|
125
|
+
x.grad=gx
|
|
126
|
+
else:
|
|
127
|
+
x.grad=x.grad+gx
|
|
128
|
+
if x.creator is not None:
|
|
129
|
+
#funcs.append(x.creator)
|
|
130
|
+
add_func(x.creator)
|
|
131
|
+
def unchain_backward(self):
|
|
132
|
+
if self.creator is not None:
|
|
133
|
+
funcs=[self.creator]
|
|
134
|
+
while funcs:
|
|
135
|
+
f=funcs.pop()
|
|
136
|
+
for x in f.inputs:
|
|
137
|
+
if x.creator is not None:
|
|
138
|
+
x.unchain()
|
|
139
|
+
class Operation:
|
|
140
|
+
def __call__(self,*inputs):
|
|
141
|
+
inputs=[as_datafield(x) for x in inputs]
|
|
142
|
+
xs=[i.data for i in inputs]
|
|
143
|
+
ys=self.forward(*xs)
|
|
144
|
+
if not isinstance(ys,tuple):
|
|
145
|
+
ys=(ys,)
|
|
146
|
+
outputs=[Datafield(as_array(y)) for y in ys]
|
|
147
|
+
if Config.enable_backprop:
|
|
148
|
+
self.generation=max([x.generation for x in inputs])
|
|
149
|
+
for output in outputs:
|
|
150
|
+
output.set_creator(self)
|
|
151
|
+
self.inputs = inputs
|
|
152
|
+
self.outputs=[weakref.ref(output) for output in outputs]
|
|
153
|
+
return outputs if len(outputs)>1 else outputs[0]
|
|
154
|
+
def forward(self,*xs):
|
|
155
|
+
raise NotImplementedError()
|
|
156
|
+
def backward(self,*xs):
|
|
157
|
+
raise NotImplementedError()
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
class Pow(Operation):
|
|
161
|
+
def __init__(self,c):
|
|
162
|
+
self.c=c
|
|
163
|
+
def forward(self,x):
|
|
164
|
+
y=x**self.c
|
|
165
|
+
return y
|
|
166
|
+
def backward(self,gy):
|
|
167
|
+
x, = self.inputs
|
|
168
|
+
c=self.c
|
|
169
|
+
gx=c*x**(c-1)*gy
|
|
170
|
+
return gx
|
|
171
|
+
class Div(Operation):
|
|
172
|
+
def forward(self,x0,x1):
|
|
173
|
+
self.x0_shape, self.x1_shape = x0.shape, x1.shape
|
|
174
|
+
y=x0/x1
|
|
175
|
+
return y
|
|
176
|
+
def backward(self,gy):
|
|
177
|
+
x0,x1=self.inputs
|
|
178
|
+
|
|
179
|
+
gx0=gy/x1
|
|
180
|
+
gx1=gy*(-x0/x1**2)
|
|
181
|
+
if self.x0_shape!=self.x1_shape:
|
|
182
|
+
gx0=nodev.operations.sum_to(gx0,self.x0_shape)
|
|
183
|
+
gx1 = nodev.operations.sum_to(gx1, self.x1_shape)
|
|
184
|
+
return gx0,gx1
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
class Add(Operation):
|
|
188
|
+
def forward(self,x0,x1):
|
|
189
|
+
self.x0_shape,self.x1_shape=x0.shape,x1.shape
|
|
190
|
+
y=x0+x1
|
|
191
|
+
return y
|
|
192
|
+
def backward(self,gy):
|
|
193
|
+
gx0,gx1=gy,gy
|
|
194
|
+
if self.x0_shape!=self.x1_shape:
|
|
195
|
+
gx0=nodev.operations.sum_to(gx0,self.x0_shape)
|
|
196
|
+
gx1 = nodev.operations.sum_to(gx1, self.x1_shape)
|
|
197
|
+
return gx0,gx1
|
|
198
|
+
|
|
199
|
+
class Neg(Operation):
|
|
200
|
+
def forward(self,x):
|
|
201
|
+
return -x
|
|
202
|
+
def backward(self,gy):
|
|
203
|
+
return -gy
|
|
204
|
+
class Mul(Operation):
|
|
205
|
+
def forward(self,x0,x1):
|
|
206
|
+
self.x0_shape, self.x1_shape = x0.shape, x1.shape
|
|
207
|
+
y=x0*x1
|
|
208
|
+
return y
|
|
209
|
+
def backward(self,gy):
|
|
210
|
+
x0,x1=self.inputs
|
|
211
|
+
gx0,gx1=x1*gy,x0*gy
|
|
212
|
+
if self.x0_shape!=self.x1_shape:
|
|
213
|
+
gx0=nodev.operations.sum_to(gx0,self.x0_shape)
|
|
214
|
+
gx1 = nodev.operations.sum_to(gx1, self.x1_shape)
|
|
215
|
+
return gx0,gx1
|
|
216
|
+
class Sub(Operation):
|
|
217
|
+
def forward(self,x0,x1):
|
|
218
|
+
self.x0_shape, self.x1_shape = x0.shape, x1.shape
|
|
219
|
+
y=x0-x1
|
|
220
|
+
return y
|
|
221
|
+
def backward(self,gy):
|
|
222
|
+
gx0,gx1=gy,-gy
|
|
223
|
+
if self.x0_shape!=self.x1_shape:
|
|
224
|
+
gx0=nodev.operations.sum_to(gx0,self.x0_shape)
|
|
225
|
+
gx1 = nodev.operations.sum_to(gx1, self.x1_shape)
|
|
226
|
+
return gx0,gx1
|
|
227
|
+
|
|
228
|
+
class Formpara(Datafield):
|
|
229
|
+
pass
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
@contextmanager
|
|
235
|
+
def test_mode():
|
|
236
|
+
old_value = Config.train
|
|
237
|
+
Config.train = False
|
|
238
|
+
try:
|
|
239
|
+
yield
|
|
240
|
+
finally:
|
|
241
|
+
Config.train = old_value
|
|
242
|
+
|
|
243
|
+
@contextmanager
|
|
244
|
+
def using_config(name,value):
|
|
245
|
+
old_value=getattr(Config,name)
|
|
246
|
+
setattr(Config,name,value)
|
|
247
|
+
try:
|
|
248
|
+
yield
|
|
249
|
+
finally:
|
|
250
|
+
setattr(Config,name,old_value)
|
|
251
|
+
def as_datafield(obj): #转换普通数据为variable
|
|
252
|
+
if isinstance(obj, Datafield):
|
|
253
|
+
return obj
|
|
254
|
+
return Datafield(as_array(obj))
|
|
255
|
+
def div(x0,x1):
|
|
256
|
+
x1 = as_array(x1, nodev.cuda.get_array_module(x0.data))
|
|
257
|
+
return Div()(x0,x1)
|
|
258
|
+
def rdiv(x0,x1):
|
|
259
|
+
x1 = as_array(x1, nodev.cuda.get_array_module(x0.data))
|
|
260
|
+
return Div()(x1,x0)
|
|
261
|
+
def sub(x1,x2):
|
|
262
|
+
return Sub()(x1,x2)
|
|
263
|
+
|
|
264
|
+
def as_array(x,array_module=np):
|
|
265
|
+
""" if x is None: # ⭐必须加
|
|
266
|
+
return None"""
|
|
267
|
+
if np.isscalar(x):
|
|
268
|
+
return array_module.array(x)
|
|
269
|
+
return x
|
|
270
|
+
def pow(x,c):
|
|
271
|
+
return Pow(c)(x)
|
|
272
|
+
|
|
273
|
+
def add(x0,x1):
|
|
274
|
+
x1=as_array(x1,nodev.cuda.get_array_module(x0.data))
|
|
275
|
+
return Add()(x0,x1)
|
|
276
|
+
def mul(x0,x1):
|
|
277
|
+
x1 = as_array(x1, nodev.cuda.get_array_module(x0.data))
|
|
278
|
+
return Mul()(x0,x1)
|
|
279
|
+
def neg(x):
|
|
280
|
+
return Neg()(x)
|
|
281
|
+
def rsub(x0,x1):
|
|
282
|
+
x1=as_array(x1)
|
|
283
|
+
return Sub()(x1,x0)
|
|
284
|
+
def no_grad():
|
|
285
|
+
return using_config('enable_backprop',False)
|
|
286
|
+
|
|
287
|
+
def setup_datafield():
|
|
288
|
+
Datafield.__mul__ = mul
|
|
289
|
+
Datafield.__add__ = add
|
|
290
|
+
Datafield.__rmul__ = mul
|
|
291
|
+
Datafield.__radd__ = add
|
|
292
|
+
Datafield.__neg__ = neg
|
|
293
|
+
Datafield.__pow__ = pow
|
|
294
|
+
Datafield.__truediv__ = div
|
|
295
|
+
Datafield.__rtruediv__ = rdiv
|
|
296
|
+
Datafield.__sub__ = sub
|
|
297
|
+
Datafield.__rsub__ = rsub
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
gpu_enable=True
|
|
3
|
+
try:
|
|
4
|
+
import cupy as cp
|
|
5
|
+
cupy=cp
|
|
6
|
+
except ImportError:
|
|
7
|
+
gpu_enable=False
|
|
8
|
+
from nodev import Datafield
|
|
9
|
+
def get_array_module(x):
|
|
10
|
+
if isinstance(x, Datafield):
|
|
11
|
+
x=x.data
|
|
12
|
+
if not gpu_enable:
|
|
13
|
+
return np
|
|
14
|
+
xp=cp.get_array_module(x)
|
|
15
|
+
return xp
|
|
16
|
+
def as_numpy(x):
|
|
17
|
+
if isinstance(x, Datafield):
|
|
18
|
+
x=x.data
|
|
19
|
+
if np.isscalar(x):
|
|
20
|
+
return np.array(x)
|
|
21
|
+
def as_cupy(x):
|
|
22
|
+
if isinstance(x, Datafield):
|
|
23
|
+
x = x.data
|
|
24
|
+
if not gpu_enable:
|
|
25
|
+
|
|
26
|
+
raise Exception('CuPy无法使用,请检查是否安装')
|
|
27
|
+
return cp.asarray(x)
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import math
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
from nodev import cuda
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Dataloader:
|
|
8
|
+
def __init__(self,dataset,batch_size,shuffle=True,gpu=False):
|
|
9
|
+
self.dataset=dataset
|
|
10
|
+
self.batch_size=batch_size
|
|
11
|
+
self.shuffle=shuffle
|
|
12
|
+
self.data_size=len(dataset)
|
|
13
|
+
self.gpu=gpu
|
|
14
|
+
self.max_iter=math.ceil(self.data_size/batch_size)
|
|
15
|
+
self.reset()
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def reset(self):
|
|
19
|
+
self.iteration=0
|
|
20
|
+
if self.shuffle:
|
|
21
|
+
self.index=np.random.permutation(len(self.dataset))
|
|
22
|
+
else:
|
|
23
|
+
self.index=np.arange(len(self.dataset))
|
|
24
|
+
def __iter__(self):
|
|
25
|
+
return self
|
|
26
|
+
|
|
27
|
+
def __next__(self):
|
|
28
|
+
if self.iteration>=self.max_iter:
|
|
29
|
+
self.reset()
|
|
30
|
+
raise StopIteration
|
|
31
|
+
i,batch_size=self.iteration,self.batch_size
|
|
32
|
+
batch_index=self.index[i*batch_size:(i+1)*batch_size]
|
|
33
|
+
batch=[self.dataset[i] for i in batch_index]
|
|
34
|
+
xp=cuda.cupy if self.gpu else np
|
|
35
|
+
x=xp.array([example[0] for example in batch])
|
|
36
|
+
t = xp.array([example[1] for example in batch])
|
|
37
|
+
self.iteration+=1
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
return x,t
|
|
41
|
+
def next(self):
|
|
42
|
+
return self.__next__()
|
|
43
|
+
def to_cpu(self):
|
|
44
|
+
self.gpu=False
|
|
45
|
+
|
|
46
|
+
def to_gpu(self):
|
|
47
|
+
self.gpu = True
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class SeqDataLoader(Dataloader):
|
|
52
|
+
def __init__(self,dataset,batch_size,gpu=False):
|
|
53
|
+
super().__init__(dataset=dataset,batch_size=batch_size,shuffle=False,gpu=gpu)
|
|
54
|
+
def __next__(self):
|
|
55
|
+
if self.iteration>=self.max_iter:
|
|
56
|
+
self.reset()
|
|
57
|
+
raise StopIteration
|
|
58
|
+
jump=self.data_size//self.batch_size
|
|
59
|
+
batch_index=[(i*jump+self.iteration)%self.data_size for i in range(self.batch_size)]
|
|
60
|
+
batch=[self.dataset[i] for i in batch_index]
|
|
61
|
+
xp=cuda.cupy if self.gpu else np
|
|
62
|
+
x=xp.array([example[0] for example in batch])
|
|
63
|
+
t = xp.array([example[1] for example in batch])
|
|
64
|
+
self.iteration+=1
|
|
65
|
+
return x,t
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
|
|
2
|
+
import numpy as np
|
|
3
|
+
|
|
4
|
+
from nodev.transforms import Compose, Flatten, ToFloat, Normalize
|
|
5
|
+
|
|
6
|
+
class Dataset():
|
|
7
|
+
def __init__(self,train=True,transform=None,target_transform=None):
|
|
8
|
+
self.train=train
|
|
9
|
+
self.transform=transform
|
|
10
|
+
self.target_transform=target_transform
|
|
11
|
+
if self.transform is None:
|
|
12
|
+
self.transform=lambda x:x
|
|
13
|
+
if self.target_transform is None:
|
|
14
|
+
self.target_transform = lambda x: x
|
|
15
|
+
|
|
16
|
+
self.data=None
|
|
17
|
+
self.label=None
|
|
18
|
+
self.prepare()
|
|
19
|
+
def __getitem__(self, index):
|
|
20
|
+
assert np.isscalar(index)
|
|
21
|
+
if self.label is None:
|
|
22
|
+
return self.transform(self.data[index]),None
|
|
23
|
+
else:
|
|
24
|
+
return self.transform(self.data[index]),\
|
|
25
|
+
self.target_transform(self.label[index])
|
|
26
|
+
def prepare(self):
|
|
27
|
+
pass
|
|
28
|
+
def __len__(self):
|
|
29
|
+
return len(self.data)
|
|
30
|
+
|
|
31
|
+
class Spiral(Dataset):
|
|
32
|
+
""" def __init__(self,train=True):
|
|
33
|
+
super().__init__()"""
|
|
34
|
+
def prepare(self):
|
|
35
|
+
self.data,self.label=get_spiral(self.train)
|
|
36
|
+
|
|
37
|
+
class Bigdata(Dataset):
|
|
38
|
+
def __getitem__(self,index):
|
|
39
|
+
x=np.load('data/{}.npy'.format(index))
|
|
40
|
+
t = np.load('label/{}.npy'.format(index))
|
|
41
|
+
return x,t
|
|
42
|
+
def __len__(self):
|
|
43
|
+
return 1000000
|
|
44
|
+
def get_spiral(train=True):
|
|
45
|
+
seed = 1984 if train else 2020
|
|
46
|
+
np.random.seed(seed)
|
|
47
|
+
|
|
48
|
+
num_data = 100
|
|
49
|
+
num_class = 3
|
|
50
|
+
input_dim = 2
|
|
51
|
+
|
|
52
|
+
data_size = num_class * num_data
|
|
53
|
+
x = np.zeros((data_size, input_dim), dtype=np.float32)
|
|
54
|
+
t = np.zeros(data_size, dtype=np.int32)
|
|
55
|
+
|
|
56
|
+
for j in range(num_class):
|
|
57
|
+
for i in range(num_data):
|
|
58
|
+
rate = i / num_data
|
|
59
|
+
r = rate
|
|
60
|
+
theta = j * 4.0 + 4.0 * rate + np.random.randn() * 0.2
|
|
61
|
+
ix = num_data * j + i
|
|
62
|
+
|
|
63
|
+
x[ix] = [r*np.sin(theta), r*np.cos(theta)]
|
|
64
|
+
t[ix] = j
|
|
65
|
+
|
|
66
|
+
return x, t
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class ImageNet(Dataset):
|
|
70
|
+
def __init__(self):
|
|
71
|
+
super().__init__()
|
|
72
|
+
@staticmethod
|
|
73
|
+
def labels():
|
|
74
|
+
path = 'models/labels'
|
|
75
|
+
with open(path, 'r') as f:
|
|
76
|
+
labels = eval(f.read())
|
|
77
|
+
return labels
|
|
78
|
+
"""class MNIST(Dataset):
|
|
79
|
+
|
|
80
|
+
def __init__(self, train=True,
|
|
81
|
+
transform=Compose([Flatten(), ToFloat(),
|
|
82
|
+
Normalize(0., 255.)]),
|
|
83
|
+
target_transform=None):
|
|
84
|
+
super().__init__(train, transform, target_transform)
|
|
85
|
+
|
|
86
|
+
def prepare(self):
|
|
87
|
+
|
|
88
|
+
if self.train:
|
|
89
|
+
data_path = "./data/train-images.idx3-ubyte"
|
|
90
|
+
label_path = "./data/train-labels.idx1-ubyte"
|
|
91
|
+
else:
|
|
92
|
+
data_path = "./data/t10k-images.idx3-ubyte"
|
|
93
|
+
label_path = "./data/t10k-labels.idx1-ubyte"
|
|
94
|
+
self.data = self._load_data(data_path)
|
|
95
|
+
self.label = self._load_label(label_path)
|
|
96
|
+
|
|
97
|
+
def _load_label(self, filepath):
|
|
98
|
+
with gzip.open(filepath, 'rb') as f:
|
|
99
|
+
labels = np.frombuffer(f.read(), np.uint8, offset=8)
|
|
100
|
+
return labels
|
|
101
|
+
|
|
102
|
+
def _load_data(self, filepath):
|
|
103
|
+
with gzip.open(filepath, 'rb') as f:
|
|
104
|
+
data = np.frombuffer(f.read(), np.uint8, offset=16)
|
|
105
|
+
data = data.reshape(-1, 1, 28, 28)
|
|
106
|
+
return data
|
|
107
|
+
|
|
108
|
+
def show(self, row=10, col=10):
|
|
109
|
+
H, W = 28, 28
|
|
110
|
+
img = np.zeros((H * row, W * col))
|
|
111
|
+
for r in range(row):
|
|
112
|
+
for c in range(col):
|
|
113
|
+
img[r * H:(r + 1) * H, c * W:(c + 1) * W] = self.data[
|
|
114
|
+
np.random.randint(0, len(self.data) - 1)].reshape(H, W)
|
|
115
|
+
plt.imshow(img, cmap='gray', interpolation='nearest')
|
|
116
|
+
plt.axis('off')
|
|
117
|
+
plt.show()
|
|
118
|
+
|
|
119
|
+
@staticmethod
|
|
120
|
+
def labels():
|
|
121
|
+
return {0: '0', 1: '1', 2: '2', 3: '3', 4: '4', 5: '5', 6: '6', 7: '7', 8: '8', 9: '9'}
|
|
122
|
+
"""
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
class MNIST(Dataset):
|
|
126
|
+
|
|
127
|
+
def __init__(self, train=True,
|
|
128
|
+
transform=Compose([Flatten(), ToFloat(),
|
|
129
|
+
Normalize(0., 255.)]),
|
|
130
|
+
target_transform=None):
|
|
131
|
+
super().__init__(train, transform, target_transform)
|
|
132
|
+
|
|
133
|
+
def prepare(self):
|
|
134
|
+
|
|
135
|
+
if self.train:
|
|
136
|
+
data_path = "data/train-images.idx3-ubyte"
|
|
137
|
+
label_path = "data/train-labels.idx1-ubyte"
|
|
138
|
+
else:
|
|
139
|
+
data_path = "data/t10k-images.idx3-ubyte"
|
|
140
|
+
label_path = "data/t10k-labels.idx1-ubyte"
|
|
141
|
+
|
|
142
|
+
self.data = self._load_images(data_path)
|
|
143
|
+
self.label = self._load_labels(label_path)
|
|
144
|
+
|
|
145
|
+
def _load_images(self, path):
|
|
146
|
+
|
|
147
|
+
with open(path, 'rb') as f:
|
|
148
|
+
data = np.frombuffer(f.read(), np.uint8, offset=16)
|
|
149
|
+
|
|
150
|
+
#data = data.reshape(-1, 784)
|
|
151
|
+
data = data.reshape(-1, 28, 28)
|
|
152
|
+
return data
|
|
153
|
+
|
|
154
|
+
def _load_labels(self, path):
|
|
155
|
+
|
|
156
|
+
with open(path, 'rb') as f:
|
|
157
|
+
labels = np.frombuffer(f.read(), np.uint8, offset=8)
|
|
158
|
+
|
|
159
|
+
return labels
|
|
160
|
+
def __len__(self):
|
|
161
|
+
return len(self.data)
|
|
162
|
+
|
|
163
|
+
def __getitem__(self, idx):
|
|
164
|
+
image = self.data[idx]
|
|
165
|
+
label = self.label[idx]
|
|
166
|
+
|
|
167
|
+
if self.transform:
|
|
168
|
+
image = self.transform(image)
|
|
169
|
+
|
|
170
|
+
return image, label
|
|
171
|
+
class SinCurve(Dataset):
|
|
172
|
+
|
|
173
|
+
def prepare(self):
|
|
174
|
+
num_data = 1000
|
|
175
|
+
dtype = np.float64
|
|
176
|
+
|
|
177
|
+
x = np.linspace(0, 2 * np.pi, num_data)
|
|
178
|
+
noise_range = (-0.05, 0.05)
|
|
179
|
+
noise = np.random.uniform(noise_range[0], noise_range[1], size=x.shape) #生成均匀分布随机数
|
|
180
|
+
if self.train:
|
|
181
|
+
y = np.sin(x) + noise
|
|
182
|
+
else:
|
|
183
|
+
y = np.cos(x)
|
|
184
|
+
y = y.astype(dtype)
|
|
185
|
+
self.data = y[:-1][:, np.newaxis]
|
|
186
|
+
self.label = y[1:][:, np.newaxis]
|