timm documentation
Ekstraksi Fitur
Ekstraksi Fitur
Semua model di timm memiliki mekanisme yang konsisten untuk memperoleh berbagai jenis fitur dari model untuk tugas selain klasifikasi.
Fitur Lapisan Kedua dari Akhir (Fitur Pra-Klasifikator)
Fitur dari lapisan model penultimate dapat diperoleh dengan beberapa cara tanpa memerlukan operasi pada model (meskipun silakan melakukan operasi jika diinginkan). Pertama, harus ditentukan apakah fitur yang diinginkan adalah fitur pooled atau un-pooled.
Tidak dipool
Ada tiga cara untuk memperoleh fitur yang tidak dipooling. Fitur akhir yang tidak dipooling ini kadang disebut sebagai state tersembunyi terakhir. Di timm, ini mencakup hingga dan termasuk lapisan normalisasi akhir (misalnya pada model bergaya ViT), tetapi tidak mencakup pemilihan pooling / token kelas serta lapisan pasca-pooling akhir.
Tanpa memodifikasi jaringan, Anda dapat memanggil model.forward_features(input) pada model apa pun sebagai pengganti model(input) yang biasa. Hal ini akan melewati head classifier dan global pooling untuk jaringan.
Jika seseorang ingin secara eksplisit memodifikasi jaringan untuk mengembalikan fitur yang tidak dipooling, mereka dapat membuat model tanpa klasifikator dan pooling, atau menghapusnya kemudian. Kedua jalur tersebut menghapus parameter yang terkait dengan klasifikator dari jaringan.
forward_features()
>>> import torch
>>> import timm
>>> m = timm.create_model('xception41', pretrained=True)
>>> o = m(torch.randn(2, 3, 299, 299))
>>> print(f'Original shape: {o.shape}')
>>> o = m.forward_features(torch.randn(2, 3, 299, 299))
>>> print(f'Unpooled shape: {o.shape}')Output:
Original shape: torch.Size([2, 1000]) Unpooled shape: torch.Size([2, 2048, 10, 10])
Buat tanpa klasifikator dan pooling
>>> import torch
>>> import timm
>>> m = timm.create_model('resnet50', pretrained=True, num_classes=0, global_pool='')
>>> o = m(torch.randn(2, 3, 224, 224))
>>> print(f'Unpooled shape: {o.shape}')Output:
Unpooled shape: torch.Size([2, 2048, 7, 7])
Hapus nanti
>>> import torch
>>> import timm
>>> m = timm.create_model('densenet121', pretrained=True)
>>> o = m(torch.randn(2, 3, 224, 224))
>>> print(f'Original shape: {o.shape}')
>>> m.reset_classifier(0, '')
>>> o = m(torch.randn(2, 3, 224, 224))
>>> print(f'Unpooled shape: {o.shape}')Output:
Original shape: torch.Size([2, 1000]) Unpooled shape: torch.Size([2, 1024, 7, 7])
Menggabungkan output tanpa pooling ke klasifikator
State tersembunyi terakhir dapat dimasukkan kembali ke bagian kepala model menggunakan fungsi forward_head().
>>> model = timm.create_model('vit_medium_patch16_reg1_gap_256', pretrained=True)
>>> output = model.forward_features(torch.randn(2,3,256,256))
>>> print('Unpooled output shape:', output.shape)
>>> classified = model.forward_head(output)
>>> print('Classification output shape:', classified.shape)Output:
Unpooled output shape: torch.Size([2, 257, 512]) Classification output shape: torch.Size([2, 1000])
Pooled
Untuk memodifikasi jaringan agar mengembalikan fitur yang telah dipooling, Anda dapat menggunakan forward_features() dan melakukan pooling/penyederhanaan hasil tersebut sendiri, atau memodifikasi jaringan seperti di atas tetapi tetap mempertahankan pooling.
Buat tanpa klasifikator
>>> import torch
>>> import timm
>>> m = timm.create_model('resnet50', pretrained=True, num_classes=0)
>>> o = m(torch.randn(2, 3, 224, 224))
>>> print(f'Pooled shape: {o.shape}')Output:
Pooled shape: torch.Size([2, 2048])
Hapus nanti
>>> import torch
>>> import timm
>>> m = timm.create_model('ese_vovnet19b_dw', pretrained=True)
>>> o = m(torch.randn(2, 3, 224, 224))
>>> print(f'Original shape: {o.shape}')
>>> m.reset_classifier(0)
>>> o = m(torch.randn(2, 3, 224, 224))
>>> print(f'Pooled shape: {o.shape}')Output:
Original shape: torch.Size([2, 1000]) Pooled shape: torch.Size([2, 1024])
Peta Fitur Multi-skala (Piramida Fitur)
Deteksi objek, segmentasi, keypoint, dan berbagai tugas piksel padat memerlukan akses ke peta fitur dari jaringan backbone pada beberapa skala. Hal ini sering dilakukan dengan memodifikasi jaringan klasifikasi asli. Karena setiap jaringan memiliki struktur yang cukup bervariasi, tidak jarang hanya beberapa backbone yang didukung dalam pustaka deteksi objek atau segmentasi tertentu.
timm memungkinkan antarmuka yang konsisten untuk membuat model mana pun yang disertakan sebagai tulang punggung fitur yang menghasilkan peta fitur untuk level yang dipilih.
Feature backbone dapat dibuat dengan menambahkan argumen features_only=True ke pemanggilan create_model mana pun. Secara default, sebagian besar model dengan hierarki fitur akan mengoutput hingga 5 fitur hingga reduksi 32. Namun, hal ini bervariasi per model; beberapa model memiliki tingkat hierarki yang lebih sedikit, dan beberapa (seperti ViT) memiliki jumlah peta fitur non-hierarkis yang lebih besar dan secara default mengoutput 3 terakhir. Argumen out_indices dapat diteruskan ke create_model untuk menentukan fitur mana yang Anda inginkan.
Buat model ekstraksi peta fitur
>>> import torch
>>> import timm
>>> m = timm.create_model('resnest26d', features_only=True, pretrained=True)
>>> o = m(torch.randn(2, 3, 224, 224))
>>> for x in o:
... print(x.shape)Output:
torch.Size([2, 64, 112, 112]) torch.Size([2, 256, 56, 56]) torch.Size([2, 512, 28, 28]) torch.Size([2, 1024, 14, 14]) torch.Size([2, 2048, 7, 7])
Kueri informasi fitur
Setelah feature backbone dibuat, backbone tersebut dapat di-query untuk menyediakan informasi reduksi channel atau resolusi ke heads downstream tanpa memerlukan konfigurasi statis atau konstanta yang di-hardcode. Atribut .feature_info adalah sebuah class yang mengenkapsulasi informasi tentang titik-titik ekstraksi fitur.
>>> import torch
>>> import timm
>>> m = timm.create_model('regnety_032', features_only=True, pretrained=True)
>>> print(f'Feature channels: {m.feature_info.channels()}')
>>> o = m(torch.randn(2, 3, 224, 224))
>>> for x in o:
... print(x.shape)Output:
Feature channels: [32, 72, 216, 576, 1512] torch.Size([2, 32, 112, 112]) torch.Size([2, 72, 56, 56]) torch.Size([2, 216, 28, 28]) torch.Size([2, 576, 14, 14]) torch.Size([2, 1512, 7, 7])
Pilih tingkat fitur tertentu atau batasi stride
Ada dua argumen pembuatan tambahan yang memengaruhi fitur output.
out_indicesmemilih indeks mana yang akan dioutputoutput_stridemembatasi langkah keluaran fitur dari jaringan (juga berfungsi dalam mode klasifikasi, btw)
Pemilihan indeks output
Argumen out_indices didukung oleh semua model, tetapi tidak semua model memiliki pemetaan indeks ke langkah fitur yang sama. Lihat kode atau periksa feature_info untuk membandingkan. Indeks keluaran umumnya sesuai dengan level fitur C(i+1)th (reduksi 2^(i+1)). Untuk sebagian besar model convnet, indeks 0 adalah fitur dengan langkah 2, dan indeks 4 adalah langkah 32. Untuk banyak model ViT atau hibrida ViT-Conv, mungkin ada banyak hingga semua peta fitur dengan bentuk yang sama, atau kombinasi peta fitur hierarkis dan non-hierarkis. Sebaiknya lihat atribut feature_info untuk melihat jumlah fitur, jumlah channel yang sesuai, dan level reduksinya.
out_indices mendukung indeks negatif, sehingga memudahkan pengambilan feature map terakhir, kedua dari akhir, dan seterusnya. out_indices=(-2,) akan mengembalikan feature map kedua dari akhir untuk model apa pun.
Langkah keluaran (dilasi peta fitur)
output_stride dicapai dengan mengonversi lapisan untuk menggunakan konvolusi dilasi. Hal ini tidak selalu mudah dilakukan; beberapa jaringan hanya mendukung output_stride=32.
>>> import torch
>>> import timm
>>> m = timm.create_model('ecaresnet101d', features_only=True, output_stride=8, out_indices=(2, 4), pretrained=True)
>>> print(f'Feature channels: {m.feature_info.channels()}')
>>> print(f'Feature reduction: {m.feature_info.reduction()}')
>>> o = m(torch.randn(2, 3, 320, 320))
>>> for x in o:
... print(x.shape)Output:
Feature channels: [512, 2048] Feature reduction: [8, 8] torch.Size([2, 512, 40, 40]) torch.Size([2, 2048, 40, 40])
Ekstraksi peta fitur perantara yang fleksibel
Selain menggunakan features_only dengan model factory, semua model mendukung metode forward_intermediates() yang menyediakan mekanisme fleksibel untuk mengekstrak peta fitur antara dan last hidden state (yang dapat dirangkai ke head). Selain itu, metode ini mendukung beberapa fitur spesifik model, seperti mengembalikan token kelas atau token prefix distill untuk beberapa model.
Menyertai fungsi forward_intermediates adalah fungsi prune_intermediate_layers yang memungkinkan pemangkasan lapisan dari model, termasuk head, final norm, dan/atau blok/tahapan akhir yang tidak diperlukan.
Argumen indices digunakan untuk forward_intermediates() dan prune_intermediate_layers() guna memilih fitur yang akan dikembalikan atau lapisan yang akan dihapus. Sama seperti out_indices untuk API features_only, indices bersifat spesifik model dan memilih intermediate mana yang akan dikembalikan.
Pada model berbasis blok non-hierarkis seperti ViT, indeksnya sesuai dengan blok, sedangkan pada model dengan tahap hierarkis, indeks biasanya sesuai dengan keluaran dari stem + setiap tahap hierarkis. Pengindeksan positif (dari awal) dan negatif (relatif terhadap akhir) keduanya berfungsi, dan None digunakan untuk mengembalikan semua intermediat.
Pemanggilan prune_intermediate_layers() mengembalikan variabel indeks, karena indeks negatif harus dikonversi menjadi indeks absolut (positif) saat model dipangkas.
model = timm.create_model('vit_medium_patch16_reg1_gap_256', pretrained=True)
output, intermediates = model.forward_intermediates(torch.randn(2,3,256,256))
for i, o in enumerate(intermediates):
print(f'Feat index: {i}, shape: {o.shape}')Feat index: 0, shape: torch.Size([2, 512, 16, 16]) Feat index: 1, shape: torch.Size([2, 512, 16, 16]) Feat index: 2, shape: torch.Size([2, 512, 16, 16]) Feat index: 3, shape: torch.Size([2, 512, 16, 16]) Feat index: 4, shape: torch.Size([2, 512, 16, 16]) Feat index: 5, shape: torch.Size([2, 512, 16, 16]) Feat index: 6, shape: torch.Size([2, 512, 16, 16]) Feat index: 7, shape: torch.Size([2, 512, 16, 16]) Feat index: 8, shape: torch.Size([2, 512, 16, 16]) Feat index: 9, shape: torch.Size([2, 512, 16, 16]) Feat index: 10, shape: torch.Size([2, 512, 16, 16]) Feat index: 11, shape: torch.Size([2, 512, 16, 16])
model = timm.create_model('vit_medium_patch16_reg1_gap_256', pretrained=True)
print('Original params:', sum([p.numel() for p in model.parameters()]))
indices = model.prune_intermediate_layers(indices=(-2,), prune_head=True, prune_norm=True) # prune head, norm, last block
print('Pruned params:', sum([p.numel() for p in model.parameters()]))
intermediates = model.forward_intermediates(torch.randn(2,3,256,256), indices=indices, intermediates_only=True) # return penultimate intermediate
for o in intermediates:
print(f'Feat shape: {o.shape}')Original params: 38880232 Pruned params: 35212800 Feat shape: torch.Size([2, 512, 16, 16])