<jupyter_start><jupyter_text>Models API and Pretrained weights  List of models supported by `timm` `timm` supports a wide variety of pretrained and non-pretrained models for number of Image based tasks. To get a complete list of models, use the `list_models` function from `timm` as below. The `list_models` function returns a list of models ordered alphabetically that are supported by `timm`. We just look at the top-5 models below.<jupyter_code>import timm 

timm.list_models()[:5]<jupyter_output><empty_output><jupyter_text>In general, you always want to use factory functions inside `timm`. Particularly, you want to use `create_model` function from `timm` to create any model. It is possible to create any of the models listed in `timm.list_models()` using the `create_model` function. There are also some wonderful extra features that we will look at later. But, let's see a quick example.<jupyter_code>import random
import torch

random_model_to_create = random.choice(timm.list_models())
random_model_to_create
model = timm.create_model(random_model_to_create)
x     = torch.randn(1, 3, 224, 224)
model(x).shape<jupyter_output><empty_output><jupyter_text>In the example above, we randomly select a model name in `timm.list_models()`, create it and pass some dummy input data through the model to get some output. In general, you never want to create random models like this, and it's only an example to showcase that all models in `timm.list_models()` are supported by `timm.create_model()` function. It's really that easy to create a model using `timm`.   Does `timm` have pretrained weights for these models? Of course! `timm` wants to make it super easy for researchers and practioners to experiment and supports a whole lot of models with pretrained weights. These pretrained weights are either:1. Directly used from their original sources2. Ported by Ross from their original implementation in a different framework (e.g. Tensorflow models)3. Trained from scratch using the included training script (`train.py`). The exact commands with hyperparameters to train these individual models are mentioned under `Training Scripts`. To list all the models that have pretrained weights, `timm` provides a convenience parameter `pretrained` that could be passed in `list_models` function as below. We only list the top-5 returned models.<jupyter_code>timm.list_models(pretrained=True)[:5]<jupyter_output><empty_output><jupyter_text>> NOTE: Just by listing the top-5 pretrained models, we can see that `timm` does not currently have pretrained weights for models such as `cspdarknet53_iabn` or `cspresnet50d`. This is a great opportunity for new contributors with hardware availability to pretrain the models on Imagenet dataset using the training script and share these weights.   My dataset doesn't consist of 3-channel images - what now? As you might already know, ImageNet data consists of 3-chanenl RGB images. Therefore, to be able to use pretrained weights in most libraries, the model expects a 3-channel input image.   `torchvision` raises `Exception`<jupyter_code>import torchvision

m = torchvision.models.resnet34(pretrained=True)

# single-channel image (maybe x-ray)
x = torch.randn(1, 1, 224, 224)

# `torchvision` raises error
try: m(x).shape
except Exception as e: print(e)<jupyter_output>Given groups=1, weight of size [64, 3, 7, 7], expected input[1, 1, 224, 224] to have 3 channels, but got 1 channels instead<jupyter_text>As can be seen above, these pretrained weights from `torchvision` won't work with single channel input images. As a work around most practitioners convert their single channel input images to 3-channel images by copying the single channel pixels accross to create a 3-channel image.  Basically, `torchvision` above is complaining that it expects the input to have 3 channels, but got 1 channel instead.<jupyter_code># 25-channel image (maybe satellite image)
x = torch.randn(1, 25, 224, 224)

# `torchvision` raises error
try: m(x).shape
except Exception as e: print(e)<jupyter_output>Given groups=1, weight of size [64, 3, 7, 7], expected input[1, 25, 224, 224] to have 3 channels, but got 25 channels instead<jupyter_text>Again, `torchvision` raises an error and this time there is no workaround to get past this error apart from just not using pretrained weights and starting with randomly initialized weights.   `timm` has a way to handle these `exceptions`<jupyter_code>m = timm.create_model('resnet34', pretrained=True, in_chans=1)

# single channel image
x = torch.randn(1, 1, 224, 224)

m(x).shape<jupyter_output><empty_output><jupyter_text>We pass in a parameter `in_chans` to the `timm.create_model` function and this somehow just magically works! Let's see what happens with the 25-channel image?<jupyter_code>m = timm.create_model('resnet34', pretrained=True, in_chans=25)

# 25-channel image
x = torch.randn(1, 25, 224, 224)

m(x).shape<jupyter_output><empty_output><jupyter_text>This works again! :)   How is `timm` able to use pretrained weights and handle images that are not 3-channel RGB images?  `timm` does all this magic inside the `load_pretrained` function that get's called to load the pretrained weights of a model. Let's see how `timm` achieves loading of pretrained weights.<jupyter_code>from timm.models.resnet import ResNet, BasicBlock, default_cfgs
from timm.models.helpers import load_pretrained
from copy import deepcopy<jupyter_output><empty_output><jupyter_text>Below, we create a simple `resnet34` model that can take single channel images as input. We make this happen by passing in `in_chans=1` to the `ResNet` constructor class when creating the model.<jupyter_code># create resnet34 model with single channel input
resnet34_defaulg_cfg = default_cfgs['resnet34']
resnet34 = ResNet(BasicBlock, layers=[3, 4, 6, 3], in_chans=1)
resnet34.default_cfg = deepcopy(resnet34_defaulg_cfg)

resnet34.conv1
resnet34.conv1.weight.shape<jupyter_output><empty_output><jupyter_text>As we can see from the first convolution of `resnet34` above, the number of input channels is set to 1. And the `conv1` weights are of shape `[64, 1, 7, 7]`. This means that the number of input channels is 1, output channels is 64 and kernel size is `7x7`. But what about the pretrained weights? Because ImageNet consists of 3-channel input images, the pretrained for this `conv1` layer would be `[64, 3, 7, 7]`.Let's confirm that below:<jupyter_code>resnet34_defaulg_cfg<jupyter_output><empty_output><jupyter_text>Let's load the pretrained weights from the model and check the number of input channels that `conv1` expects.<jupyter_code>import torch
state_dict = torch.hub.load_state_dict_from_url(resnet34_defaulg_cfg['url'])<jupyter_output><empty_output><jupyter_text>Great, so we have loaded the pretrained weights of resnet-34 from `'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/resnet34-43635321.pth'` URL, let's now check the shape of the weights for `conv1` below:<jupyter_code># check `conv1` weight shape
state_dict['conv1.weight'].shape<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.07741296348712143, 'fraction_numerical': 0.02547410133031418, 'mean_word_length': 5.808285163776493, 'pattern_counts': {'":': 0, '<': 47, '<?xml version=': 0, '>': 48, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '12', 'dir': 'jupyter-structured-clean-dedup', 'id': '219474', 'license': 'Apache-2.0', 'n_tokens_mistral': 2213, 'n_tokens_neox': 2064, 'n_words': 878, 'path': 'nbs/00b_models.ipynb', 'repo_name': 'discipleOfExperience/timmdocs', 'size': '7066'}