首先一個模型訓練過程的基本框架:
- DataSet 數據格式化
- Dataloader 數據載入
- model 模型定義
- lossfunction 損失函數定義
- optimizer 優化器
1. DataSet
基類
class Dataset(object):
r"""An abstract class representing a :class:`Dataset`.
All datasets that represent a map from keys to data samples should subclass
it. All subclasses should overwrite :meth:`__getitem__`, supporting fetching a
data sample for a given key. Subclasses could also optionally overwrite
:meth:`__len__`, which is expected to return the size of the dataset by many
:class:`~torch.utils.data.Sampler` implementations and the default options
of :class:`~torch.utils.data.DataLoader`.
.. note::
:class:`~torch.utils.data.DataLoader` by default constructs a index
sampler that yields integral indices. To make it work with a map-style
dataset with non-integral indices/keys, a custom sampler must be provided.
"""
def __getitem__(self, index):
raise NotImplementedError
def __add__(self, other):
return ConcatDataset([self, other])
__getitem__必須重載,在Dataloader中會使用到,__getitem__方法返回單個樣本
例子:
class MyDataset(Dataset):
"""
下載數據、初始化數據,都可以在這裏完成
"""
def __init__(self):
xy = np.loadtxt('/data.txt‘) # 使用numpy讀取數據
self.x_data = torch.from_numpy(xy[:, 0:-1])
self.y_data = torch.from_numpy(xy[:, [-1]])
self.len = xy.shape[0]
def __getitem__(self, index):
return self.x_data[index], self.y_data[index]
def __len__(self):
return self.len
# 實例化
dataset = MyDataset()
2. Dataloader
import之後直接使用
from torch.utils.data import DataLoader
dataloader = DataLoader(dataset, batch_size=1)
接受的參數有:
Arguments:
dataset (Dataset): dataset from which to load the data.
batch_size (int, optional): how many samples per batch to load
(default: ``1``).
shuffle (bool, optional): set to ``True`` to have the data reshuffled
at every epoch (default: ``False``).
sampler (Sampler, optional): defines the strategy to draw samples from
the dataset. If specified, :attr:`shuffle` must be ``False``.
batch_sampler (Sampler, optional): like :attr:`sampler`, but returns a batch of
indices at a time. Mutually exclusive with :attr:`batch_size`,
:attr:`shuffle`, :attr:`sampler`, and :attr:`drop_last`.
num_workers (int, optional): how many subprocesses to use for data
loading. ``0`` means that the data will be loaded in the main process.
(default: ``0``)
collate_fn (callable, optional): merges a list of samples to form a
mini-batch of Tensor(s). Used when using batched loading from a
map-style dataset.
pin_memory (bool, optional): If ``True``, the data loader will copy Tensors
into CUDA pinned memory before returning them. If your data elements
are a custom type, or your :attr:`collate_fn` returns a batch that is a custom type,
see the example below.
drop_last (bool, optional): set to ``True`` to drop the last incomplete batch,
if the dataset size is not divisible by the batch size. If ``False`` and
the size of dataset is not divisible by the batch size, then the last batch
will be smaller. (default: ``False``)
timeout (numeric, optional): if positive, the timeout value for collecting a batch
from workers. Should always be non-negative. (default: ``0``)
worker_init_fn (callable, optional): If not ``None``, this will be called on each
worker subprocess with the worker id (an int in ``[0, num_workers - 1]``) as
input, after seeding and before data loading. (default: ``None``)
3. model
可以在INIT中定義結構,在forward中定義前向計算過程
實例化model的之後,將model作爲方法返回的是forward函數的返回值
例子:
class mymodel(nn.model):
def __init__(self, x, y):
self.x=x
self.y=y
def forward(self):
return self.x+self.y
model = mymodel(x,y)
z = model()
# z=x+y
4. loss function
損失函數,即一個X通過模型計算出來的y‘與真實的y之間的差距,這個差距又lossfunction定義。loss function需要是一個模型,要可以backward()
loss_fn = nn.CrossEntropyLoss()
或者自己定義
計算梯度:
loss = loss_fn(y',y)
loss.backward()
backward過程中,計算loss的輸入參數的梯度將被計算。
5 optimizer
optimizer相關操作
# 實例化
optimizer = optim.Adam(model.parameters(), lr=lr)
#梯度置零
optimizer.zero_grad()
# 調整參數
optimizer.step()
6. 整體流程
dataset = MyDataset()
dataloader = DataLoader(dataset, batch_size=1)
model = mymodel()
loss_fn = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=lr)
for epoch in range(n_epoches):
for i, (x,y) in enumerate(dataloader):
y_hat = model(x)
loss = loss_fn(y_hat, y)
optimizer.zero_grad()
loss.backward()
optimizer.step()