Spaces:
Sleeping
Sleeping
Download src/model.py from BerhaneW/image-super-resolution: direct link, hf CLI and curl.
- Browser
- Download file 3.75 kB
-
https://huggingface.co/spaces/BerhaneW/image-super-resolution/resolve/main/src/model.py
- Command line
-
hf download hf://spaces/BerhaneW/image-super-resolution/src/model.py
-
curl -L -o model.py https://huggingface.co/spaces/BerhaneW/image-super-resolution/resolve/main/src/model.py
3.75 kB
| import tensorflow as tf | |
| class PixelShuffle(tf.keras.layers.Layer): | |
| """ | |
| Sub-pixel convolution layer (equivalent to PyTorch's nn.PixelShuffle). | |
| Rearranges elements in a tensor of shape (N, H, W, C * r^2) | |
| into (N, H*r, W*r, C) using tf.nn.depth_to_space. | |
| """ | |
| def __init__(self, scale_factor, **kwargs): | |
| super().__init__(**kwargs) | |
| self.scale_factor = scale_factor | |
| def call(self, x): | |
| return tf.nn.depth_to_space(x, self.scale_factor) | |
| def get_config(self): | |
| config = super().get_config() | |
| config["scale_factor"] = self.scale_factor | |
| return config | |
| def build_srcnn(num_channels=3): | |
| """ | |
| Super-Resolution Convolutional Neural Network (SRCNN). | |
| Input: | |
| Bicubic-upsampled LR image with same spatial size as HR target. | |
| Output: | |
| Refined SR image of the same size. | |
| """ | |
| model = tf.keras.Sequential( | |
| [ | |
| tf.keras.layers.Input(shape=(None, None, num_channels), name="input"), | |
| tf.keras.layers.Conv2D( | |
| 64, | |
| kernel_size=9, | |
| padding="same", | |
| activation="relu", | |
| name="feature_extraction", | |
| ), | |
| tf.keras.layers.Conv2D( | |
| 32, | |
| kernel_size=1, | |
| padding="same", | |
| activation="relu", | |
| name="non_linear_mapping", | |
| ), | |
| tf.keras.layers.Conv2D( | |
| num_channels, | |
| kernel_size=5, | |
| padding="same", | |
| activation="sigmoid", | |
| name="reconstruction", | |
| ), | |
| ], | |
| name="SRCNN", | |
| ) | |
| return model | |
| def build_espcn(scale_factor=2, num_channels=3): | |
| """ | |
| Efficient Sub-Pixel Convolutional Neural Network (ESPCN). | |
| Input: | |
| Native low-resolution image. | |
| Output: | |
| High-resolution image after learned sub-pixel upscaling. | |
| Args: | |
| scale_factor: upscaling factor, e.g. 2, 3, 4, 8 | |
| num_channels: usually 3 for RGB | |
| """ | |
| inputs = tf.keras.Input(shape=(None, None, num_channels), name="lr_input") | |
| x = tf.keras.layers.Conv2D( | |
| 64, | |
| kernel_size=5, | |
| padding="same", | |
| activation="relu", | |
| name="conv1", | |
| )(inputs) | |
| x = tf.keras.layers.Conv2D( | |
| 32, | |
| kernel_size=3, | |
| padding="same", | |
| activation="relu", | |
| name="conv2", | |
| )(x) | |
| x = tf.keras.layers.Conv2D( | |
| num_channels * (scale_factor ** 2), | |
| kernel_size=3, | |
| padding="same", | |
| name="conv3", | |
| )(x) | |
| x = PixelShuffle(scale_factor, name="pixel_shuffle")(x) | |
| outputs = tf.keras.layers.Activation("sigmoid", name="output")(x) | |
| model = tf.keras.Model(inputs, outputs, name=f"ESPCN_x{scale_factor}") | |
| return model | |
| def build_model(architecture="espcn", scale_factor=2, num_channels=3): | |
| """ | |
| Factory function that builds the requested model. | |
| Args: | |
| architecture: 'srcnn' or 'espcn' | |
| scale_factor: upscale factor for ESPCN | |
| num_channels: number of image channels | |
| """ | |
| architecture = architecture.lower() | |
| if architecture == "srcnn": | |
| return build_srcnn(num_channels=num_channels) | |
| elif architecture == "espcn": | |
| return build_espcn(scale_factor=scale_factor, num_channels=num_channels) | |
| else: | |
| raise ValueError( | |
| f"Unknown architecture '{architecture}'. Choose 'srcnn' or 'espcn'." | |
| ) | |
| if __name__ == "__main__": | |
| print("=== SRCNN ===") | |
| srcnn = build_model("srcnn") | |
| srcnn.summary() | |
| for scale in [2, 3, 4, 8]: | |
| print(f"\n=== ESPCN (x{scale}) ===") | |
| espcn = build_model("espcn", scale_factor=scale) | |
| espcn.summary() | |