CFSDN nhấn mạnh vào giá trị tạo ra nguồn mở và chúng tôi cam kết xây dựng nền tảng chia sẻ tài nguyên để mọi nhân viên CNTT có thể tìm thấy thế giới tuyệt vời của bạn tại đây.
Bài viết trên blog CFSDN pytorch tinh chỉnh các thao tác mô hình được huấn luyện trước được tác giả sưu tầm và biên soạn. Nếu các bạn quan tâm đến bài viết này thì nhớ like nhé.
số 1
torchvision chứa nhiều mô hình được đào tạo trước, giúp việc tinh chỉnh trở nên rất dễ dàng. Bài viết này chủ yếu giới thiệu cách tinh chỉnh mô hình được đào tạo trước trong torchvision.
Cài đặt
Cách tinh chỉnh.
Lấy resnet18 làm ví dụ:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
từ
tầm nhìn ngọn đuốc
nhập khẩu
mô hình
từ
ngọn đuốc
nhập khẩu
không
từ
ngọn đuốc
nhập khẩu
tối ưu
mô hình resnet
=
models.resnet18(đã được đào tạo trước
=
ĐÚNG VẬY
)
resnet_model.fc
=
nn.Linear(in_features
=
..., tính năng ngoài
=
100
)
vì
ĐẾN
TRONG
danh sách
(resnet_model.parameters())[:
-
2
]:
para.requires_grad
=
SAI
trình tối ưu hóa
=
optim.SGD(params
=
[resnet_model.fc.weight, resnet_model.fc.bias], lr
=
1e
-
3
)
...
|
Tại sao
Dưới đây là phần giới thiệu về những gì xảy ra trong khung khi chạy resnet_model.fc= nn.Linear(in_features=..., out_features=100).
Lúc này, bạn nên xem phần __setattr__ của mã nguồn nn.Module, vì phương thức này sẽ được gọi khi settingattr:
?
1
2
3
4
5
|
định nghĩa
__setattr__(
bản thân
, tên, giá trị):
định nghĩa
xóa_khỏi(
*
dict):
vì
ngày
TRONG
câu nói:
nếu như
tên
TRONG
ngày:
của
d[tên]
|
Điều đầu tiên xuất hiện là hàm Remove_from. Mục đích của hàm này là loại bỏ thuộc tính cũ nếu một thuộc tính có cùng tên xuất hiện. Sử dụng ví dụ vừa đưa ra, đây là:
Có một Mô-đun có tên fc trong mô hình được đào tạo trước.
Ngoài định nghĩa lớp, chúng ta gán lại một Mô-đun khác cho fc.
Mô-đun tương ứng với fc trong định nghĩa lớp sẽ bị xóa khỏi mô hình.
Phần 2
Lời nói đầu
Bài viết này là bản tóm tắt về khởi tạo và tinh chỉnh tham số từ Diễn đàn PyTorch và đây cũng là "cách thực hành tốt nhất" mà tôi sử dụng khi viết mã. Cuối cùng, tôi mong mọi người sẽ ghé thăm diễn đàn thường xuyên hơn và sẽ có nhiều câu trả lời chất lượng.
Khởi tạo tham số
Việc khởi tạo tham số thực chất là gán giá trị cho tham số. Các tham số chúng ta cần tìm hiểu thực chất là Variable. Nó thực chất là một gói của Tensor và cung cấp các lý do như data và grad. Điều này có nghĩa là chúng ta có thể trực tiếp thao tác và gán giá trị cho các tham số này. Đây là lúc PyTorch hoạt động đơn giản và hiệu quả.

Vì vậy, chúng ta có thể thực hiện các thao tác sau để khởi tạo. Tất nhiên, có những phương pháp khác, nhưng phương pháp này được tác giả của PyTorch khuyên dùng:
?
1
2
3
4
5
6
7
8
9
|
định nghĩa
trọng lượng khởi tạo(m):
nếu như
là trường hợp
(m, nn.Conv2d):
N
=
m.kích thước_hạt_nhân[
0
]
*
m.kích thước_hạt_nhân[
1
]
*
m.out_kênh
m.trọng lượng.dữ liệu.bình thường_(
0
, toán học.sqrt(
2.
/
N))
Elif
là trường hợp
(m, nn.BatchNorm2d):
m.trọng lượng.dữ liệu.điền_(
1
)
m.bias.data.zero_()
|
Tinh chỉnh
Thông thường sau khi tải các tham số của mô hình được huấn luyện trước, chúng ta cần tinh chỉnh mô hình, có thể tinh chỉnh theo nhiều cách khác nhau.
tinh chỉnh cục bộ
Đôi khi sau khi tải mô hình huấn luyện, chúng ta chỉ muốn điều chỉnh một vài lớp cuối cùng và không huấn luyện các lớp khác. Trên thực tế, không đào tạo có nghĩa là không tính toán độ dốc require_grad được cung cấp trong PyTorch khiến việc kiểm soát quá trình đào tạo trở nên rất đơn giản.
?
1
2
3
4
5
6
7
8
9
|
người mẫu
=
torchvision.models.resnet18(đã được đào tạo trước
=
ĐÚNG VẬY
)
vì
tham số
TRONG
mô hình.tham số():
param.requires_grad
=
SAI
model.fc
=
nn.Tuyến tính(
512
,
100
)
trình tối ưu hóa
=
optim.SGD(mô hình.fc.tham số(), lr
=
1e
-
2
, động lượng
=
0,9
)
|
tinh chỉnh toàn cầu
Đôi khi chúng tôi cần tinh chỉnh toàn bộ thế giới, nhưng chúng tôi muốn lớp đã thay đổi có tốc độ học khác với các lớp khác. Tại thời điểm này, chúng tôi có thể chỉ định các tốc độ học khác nhau cho các lớp khác và các lớp mới trong trình tối ưu hóa. Ví dụ:
?
1
2
3
4
5
6
7
8
|
bỏ qua_tham_số
=
danh sách
(
bản đồ
(
nhận dạng
, mô hình.fc.parameters()))
tham số cơ sở
=
lọc
(
lambda
P:
nhận dạng
(P)
không
TRONG
bỏ qua các tham số,
mô hình.tham số())
trình tối ưu hóa
=
torch.optim.SGD([
{
'tham số'
: tham số cơ sở},
{
'tham số'
: model.fc.parameters(),
'lr'
:
1e
-
3
}
], lr
=
1e
-
2
, động lượng
=
0,9
)
|
Trong số đó, base_params sử dụng 1e-3 để huấn luyện, model.fc.parameters sử dụng 1e-2 để huấn luyện và động lượng là chung cho cả hai.
Số 3:
mô hình tinh chỉnh pytorch
Bài viết chủ yếu mô tả cách đọc tham số của các mô hình đã được huấn luyện trước đó trên pytorch và cách đọc một số tham số của mô hình khi tên mô hình đã thay đổi.
Lưu trữ và đọc mô hình pytorch
Trong quá trình lưu mô hình, mô hình và các tham số được lưu trữ cùng nhau và các tham số mô hình được lưu trữ riêng biệt.
Lưu trữ riêng các tham số mô hình
Khi lưu trữ sử dụng:
?
1
|
torch.save(the_model.state_dict(), PATH)
|
Khi đọc:
?
1
2
|
mô hình
=
Lớp mô hình(
*
các đối số,
*
*
kwargs)
the_model.load_state_dict(torch.load(PATH))
|
Lưu trữ mô hình và thông số
kho:
?
1
|
torch.save(mô hình, PATH)
|
Đọc:
?
1
|
mô hình
=
torch.load(PATH)
|
Thông số mô hình
Quá trình tinh chỉnh là đọc các tham số của mô hình gốc. Tuy nhiên, do các tập dữ liệu được mô hình xử lý khác nhau nên tổng số lớp ở lớp cuối cùng là khác nhau nên lớp cuối cùng của mô hình. cần phải sửa đổi để các tham số được mô hình đọc. Các tham số của mô hình có dạng khác với các tham số được tải xuống sau khi huấn luyện trên một tập dữ liệu lớn. Chúng ta cần viết hàm riêng để đọc các tham số.
Dạng tham số của mô hình pytorch
Các tham số của mô hình được lưu trữ dưới dạng từ điển.
?
1
2
3
|
mô hình_dict
=
mô hình_state_dict(),
vì
k, v
TRONG
model_dict.items():
in
(tiếng Anh)
|
Bạn có thể thấy tất cả các giá trị quan trọng.
Nếu muốn sửa đổi các tham số của mô hình, chỉ cần gán giá trị cho các giá trị key tương ứng.
?
1
|
mô hình_dict[k]
=
giá trị mới
|
Cuối cùng, các tham số của mô hình được cập nhật.
?
1
|
mô hình.tải_trạng_thái_dict(mô_hình_dict)
|
Nếu giá trị khóa của mô hình giống với giá trị khóa khi huấn luyện trên tập dữ liệu lớn
Chúng ta có thể đọc mô hình thông qua thuật toán sau.
?
1
2
3
4
5
6
7
8
9
10
11
|
mô hình_dict
=
mô hình.state_dict()
pretrained_dict
=
torch.load(đường dẫn mô hình)
khác biệt
=
{k:v
vì
k, v
TRONG
model_dict.items()
nếu như
\
tôi
TRONG
pretrained_dict
Và
pretrained_dict[k].kích thước()
=
=
v.kích thước()}
pretrained_dict
=
{k:v
vì
k, v
TRONG
pretrained_dict.items()
nếu như
tôi
TRONG
mô hình_dict
Và
mô hình_dict[k].kích thước()
=
=
v.kích thước()}
pretrained_dict.update(khác biệt)
model_dict.update(pretrained_dict)
mô hình.load_state_dict(mô hình_dict)
|
Nếu giá trị khóa của mô hình khác với giá trị khóa khi huấn luyện trên tập dữ liệu lớn nhưng thứ tự giống nhau
?
1
2
3
4
5
6
7
8
9
10
11
12
|
mô hình_dict
=
mô hình.state_dict()
pretrained_dict
=
torch.load(đường dẫn mô hình)
chìa khóa
=
[]
vì
k, v
TRONG
pretrained_dict.items():
keys.append(k)
Tôi
=
0
vì
k, v
TRONG
model_dict.items():
nếu như
v.kích thước()
=
=
pretrained_dict[khóa[i]].kích thước():
in
(k,
','
, phím[i])
mô hình_dict[k]
=
pretrained_dict[khóa[i]]
Tôi
=
Tôi
+
1
mô hình.load_state_dict(mô hình_dict)
|
Nếu giá trị khóa của mô hình khác với giá trị khóa khi huấn luyện trên tập dữ liệu lớn nhưng thứ tự cũng khác nhau.
Hãy tự mình tìm ra mối quan hệ tương ứng, một phím tương ứng với việc gán một phím.
Trên đây là kinh nghiệm cá nhân của mình, hi vọng có thể cho các bạn tham khảo và mong các bạn có thể ủng hộ mình.
Liên kết gốc: https://blog.csdn.net/Scythe666/article/details/82809615.
Cuối cùng, bài viết về hoạt động của mô hình được đào tạo trước bằng pytorch kết thúc ở đây. Nếu bạn muốn biết thêm về hoạt động của mô hình được đào tạo trước bằng pytorch, vui lòng tìm kiếm các bài viết CFSDN hoặc tiếp tục duyệt các bài viết liên quan. ủng hộ blog của tôi trong tương lai! .
Tôi là một lập trình viên xuất sắc, rất giỏi!