[refactor] SubImage → SubImageExtract, add SubImageCombine
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -33,7 +33,7 @@
|
|||||||
"from rbm.entity import Entity, EntityParams, TrainingParams\n",
|
"from rbm.entity import Entity, EntityParams, TrainingParams\n",
|
||||||
"from rbm.matrix import Mat, np, rms_error_accu, sample_gaussian\n",
|
"from rbm.matrix import Mat, np, rms_error_accu, sample_gaussian\n",
|
||||||
"from rbm.torch import Optimizer\n",
|
"from rbm.torch import Optimizer\n",
|
||||||
"from image.sub_image import SubImage, normalize\n",
|
"from image.sub_image import SubImageExtract, SubImageExtractCombine, normalize\n",
|
||||||
"import math\n",
|
"import math\n",
|
||||||
"import random"
|
"import random"
|
||||||
],
|
],
|
||||||
@@ -216,7 +216,7 @@
|
|||||||
"mean_training_batch = np.reshape(np.repeat(np.mean(train_images, axis=1), 3072, axis=0), train_images.shape)\n",
|
"mean_training_batch = np.reshape(np.repeat(np.mean(train_images, axis=1), 3072, axis=0), train_images.shape)\n",
|
||||||
"var_training_batch = np.reshape(np.repeat(np.std(train_images, axis=1), 3072, axis=0), train_images.shape)\n",
|
"var_training_batch = np.reshape(np.repeat(np.std(train_images, axis=1), 3072, axis=0), train_images.shape)\n",
|
||||||
"train_images_norm = (train_images - mean_training_batch) / var_training_batch\n",
|
"train_images_norm = (train_images - mean_training_batch) / var_training_batch\n",
|
||||||
"sub_generator = SubImage(PATCH, PATCH, STRIDE, STRIDE)\n",
|
"sub_generator = SubImageExtract(PATCH, PATCH, STRIDE, STRIDE)\n",
|
||||||
"train_subimages = sub_generator(np.reshape(train_images, (N, 3, 32, 32)), 3)\n",
|
"train_subimages = sub_generator(np.reshape(train_images, (N, 3, 32, 32)), 3)\n",
|
||||||
"print(train_subimages.shape)\n",
|
"print(train_subimages.shape)\n",
|
||||||
"train_subimages = np.reshape(train_subimages, (train_subimages.shape[0], N_VIS))\n",
|
"train_subimages = np.reshape(train_subimages, (train_subimages.shape[0], N_VIS))\n",
|
||||||
@@ -387,12 +387,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"source": [
|
"source": [
|
||||||
"import numpy\n",
|
"combiner = SubImageExtractCombine(PATCH, PATCH, STRIDE, STRIDE, 32, 32, n_ch=3)\n",
|
||||||
"\n",
|
"n_images = n_side\n",
|
||||||
"# Reconstruct full 32x32 images by assembling reconstructed sub-images (overlap-averaged)\n",
|
|
||||||
"nx_steps = (32 - PATCH) // STRIDE + 1\n",
|
"nx_steps = (32 - PATCH) // STRIDE + 1\n",
|
||||||
"ny_steps = (32 - PATCH) // STRIDE + 1\n",
|
"ny_steps = (32 - PATCH) // STRIDE + 1\n",
|
||||||
"n_images = n_side\n",
|
|
||||||
"\n",
|
"\n",
|
||||||
"fig, axes = plt.subplots(n_images, 2, figsize=(6, n_images * 3))\n",
|
"fig, axes = plt.subplots(n_images, 2, figsize=(6, n_images * 3))\n",
|
||||||
"\n",
|
"\n",
|
||||||
@@ -400,21 +398,10 @@
|
|||||||
" orig = np.reshape(train_images[img_idx], (3, 32, 32))\n",
|
" orig = np.reshape(train_images[img_idx], (3, 32, 32))\n",
|
||||||
" orig_display = np.asnumpy((orig - np.min(orig)) / (np.max(orig) - np.min(orig)))\n",
|
" orig_display = np.asnumpy((orig - np.min(orig)) / (np.max(orig) - np.min(orig)))\n",
|
||||||
"\n",
|
"\n",
|
||||||
" accum = numpy.zeros((3, 32, 32), dtype=numpy.float64)\n",
|
" start = img_idx * nx_steps * ny_steps\n",
|
||||||
" count = numpy.zeros((1, 32, 32), dtype=numpy.float64)\n",
|
" patches = train_subimages[start : start + nx_steps * ny_steps]\n",
|
||||||
" for ix in range(nx_steps):\n",
|
" recon_patches = np.array([model.backward(model.forward(p)) for p in patches])\n",
|
||||||
" for iy in range(ny_steps):\n",
|
" recon_full = combiner(recon_patches)\n",
|
||||||
" sub_idx = img_idx * nx_steps * ny_steps + ix * ny_steps + iy\n",
|
|
||||||
" inp = train_subimages[sub_idx]\n",
|
|
||||||
" recon = model.backward(model.forward(inp))\n",
|
|
||||||
" arr = np.asnumpy(np.reshape(recon, (3, PATCH, PATCH)))\n",
|
|
||||||
" x0, y0 = ix * STRIDE, iy * STRIDE\n",
|
|
||||||
" accum[:, x0:x0+PATCH, y0:y0+PATCH] += arr\n",
|
|
||||||
" count[0, x0:x0+PATCH, y0:y0+PATCH] += 1.0\n",
|
|
||||||
"\n",
|
|
||||||
" recon_full = (accum / numpy.maximum(count, 1)).transpose(1, 2, 0)\n",
|
|
||||||
" lo, hi = recon_full.min(), recon_full.max()\n",
|
|
||||||
" recon_full = numpy.clip((recon_full - lo) / (hi - lo + 1e-8), 0, 1)\n",
|
|
||||||
"\n",
|
"\n",
|
||||||
" axes[img_idx, 0].imshow(orig_display.transpose(1, 2, 0))\n",
|
" axes[img_idx, 0].imshow(orig_display.transpose(1, 2, 0))\n",
|
||||||
" axes[img_idx, 0].axis('off')\n",
|
" axes[img_idx, 0].axis('off')\n",
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
"from rbm.entity import Entity, EntityParams, TrainingParams\n",
|
"from rbm.entity import Entity, EntityParams, TrainingParams\n",
|
||||||
"from rbm.matrix import Mat, np, rms_error_accu\n",
|
"from rbm.matrix import Mat, np, rms_error_accu\n",
|
||||||
"from rbm.torch import Optimizer\n",
|
"from rbm.torch import Optimizer\n",
|
||||||
"from image.sub_image import SubImage\n",
|
"from image.sub_image import SubImageExtract\n",
|
||||||
"import math"
|
"import math"
|
||||||
],
|
],
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
@@ -179,7 +179,7 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"print(train_images.shape)\n",
|
"print(train_images.shape)\n",
|
||||||
"image_indices = np.random.randint(0, N-1, n_side*n_side)\n",
|
"image_indices = np.random.randint(0, N-1, n_side*n_side)\n",
|
||||||
"sub_generator = SubImage(8,8,4,4)\n",
|
"sub_generator = SubImageExtract(8,8,4,4)\n",
|
||||||
"train_subimages = sub_generator(np.reshape(train_images, (N, 28,28)), 1)\n",
|
"train_subimages = sub_generator(np.reshape(train_images, (N, 28,28)), 1)\n",
|
||||||
"print(train_subimages.shape)\n",
|
"print(train_subimages.shape)\n",
|
||||||
"train_subimages = np.reshape(train_subimages, (train_subimages.shape[0], 8*8))\n",
|
"train_subimages = np.reshape(train_subimages, (train_subimages.shape[0], 8*8))\n",
|
||||||
|
|||||||
+30
-1
@@ -1,3 +1,4 @@
|
|||||||
|
import numpy as _np
|
||||||
from rbm.matrix import Mat, np
|
from rbm.matrix import Mat, np
|
||||||
|
|
||||||
def normalize(image: Mat):
|
def normalize(image: Mat):
|
||||||
@@ -6,7 +7,7 @@ def normalize(image: Mat):
|
|||||||
std = np.where(std < 1e-8, np.ones_like(std), std)
|
std = np.where(std < 1e-8, np.ones_like(std), std)
|
||||||
return (image - mean) / std
|
return (image - mean) / std
|
||||||
|
|
||||||
class SubImage:
|
class SubImageExtract:
|
||||||
def __init__(self, sx: int, sy: int, px: int, py: int):
|
def __init__(self, sx: int, sy: int, px: int, py: int):
|
||||||
self.sx = sx
|
self.sx = sx
|
||||||
self.sy = sy
|
self.sy = sy
|
||||||
@@ -48,6 +49,34 @@ class SubImage:
|
|||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
class SubImageCombine:
|
||||||
|
def __init__(self, sx: int, sy: int, px: int, py: int, image_h: int, image_w: int, n_ch: int = 3):
|
||||||
|
self.sx = sx
|
||||||
|
self.sy = sy
|
||||||
|
self.px = px
|
||||||
|
self.py = py
|
||||||
|
self.image_h = image_h
|
||||||
|
self.image_w = image_w
|
||||||
|
self.n_ch = n_ch
|
||||||
|
|
||||||
|
def __call__(self, subimages: Mat) -> _np.ndarray:
|
||||||
|
nx = (self.image_h - self.sx) // self.px + 1
|
||||||
|
ny = (self.image_w - self.sy) // self.py + 1
|
||||||
|
|
||||||
|
accum = _np.zeros((self.n_ch, self.image_h, self.image_w), dtype=_np.float64)
|
||||||
|
count = _np.zeros((1, self.image_h, self.image_w), dtype=_np.float64)
|
||||||
|
|
||||||
|
for ix in range(nx):
|
||||||
|
for iy in range(ny):
|
||||||
|
patch = _np.asarray(np.reshape(subimages[ix * ny + iy], (self.n_ch, self.sx, self.sy)))
|
||||||
|
x0, y0 = ix * self.px, iy * self.py
|
||||||
|
accum[:, x0:x0+self.sx, y0:y0+self.sy] += patch
|
||||||
|
count[0, x0:x0+self.sx, y0:y0+self.sy] += 1.0
|
||||||
|
|
||||||
|
result = (accum / _np.maximum(count, 1)).transpose(1, 2, 0)
|
||||||
|
lo, hi = result.min(), result.max()
|
||||||
|
return _np.clip((result - lo) / (hi - lo + 1e-8), 0, 1)
|
||||||
|
|
||||||
def conv2d(image: Mat, kernel: Mat, stride: tuple[int,int]):
|
def conv2d(image: Mat, kernel: Mat, stride: tuple[int,int]):
|
||||||
pad_x = int((kernel.shape[0] - 1)/2)
|
pad_x = int((kernel.shape[0] - 1)/2)
|
||||||
pad_y = int((kernel.shape[1] - 1)/2)
|
pad_y = int((kernel.shape[1] - 1)/2)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import matplotlib.pyplot as plt
|
|||||||
|
|
||||||
from rbm.model import Model
|
from rbm.model import Model
|
||||||
from rbm.entity import Entity, EntityParams, TrainingParams
|
from rbm.entity import Entity, EntityParams, TrainingParams
|
||||||
from image.sub_image import SubImage, normalize
|
from image.sub_image import SubImageExtract, normalize
|
||||||
from rbm.matrix import Mat, np, convert
|
from rbm.matrix import Mat, np, convert
|
||||||
from rbm.status import CheckpointStatus
|
from rbm.status import CheckpointStatus
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ class TestModel(Model):
|
|||||||
|
|
||||||
|
|
||||||
def pad_to_stride(img: numpy.ndarray) -> numpy.ndarray:
|
def pad_to_stride(img: numpy.ndarray) -> numpy.ndarray:
|
||||||
"""Pad so (H - PATCH) and (W - PATCH) are divisible by STRIDE (required by SubImage.check)."""
|
"""Pad so (H - PATCH) and (W - PATCH) are divisible by STRIDE (required by SubImageExtract.check)."""
|
||||||
h, w = img.shape[:2]
|
h, w = img.shape[:2]
|
||||||
ph = (-h) % STRIDE if h >= PATCH else PATCH - h
|
ph = (-h) % STRIDE if h >= PATCH else PATCH - h
|
||||||
pw = (-w) % STRIDE if w >= PATCH else PATCH - w
|
pw = (-w) % STRIDE if w >= PATCH else PATCH - w
|
||||||
@@ -86,8 +86,8 @@ def load_patches(data_dir: str, n_images: int = N_IMAGES, start: int = 0):
|
|||||||
|
|
||||||
|
|
||||||
def load_image_patches(path: str):
|
def load_image_patches(path: str):
|
||||||
"""Extract normalised patches from a single image via SubImage; return (patches, nx_steps, ny_steps)."""
|
"""Extract normalised patches from a single image via SubImageExtract; return (patches, nx_steps, ny_steps)."""
|
||||||
sub = SubImage(PATCH, PATCH, STRIDE, STRIDE)
|
sub = SubImageExtract(PATCH, PATCH, STRIDE, STRIDE)
|
||||||
img = cv2.imread(path)
|
img = cv2.imread(path)
|
||||||
img = pad_to_stride(img)
|
img = pad_to_stride(img)
|
||||||
h, w = img.shape[:2]
|
h, w = img.shape[:2]
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
from image.sub_image import SubImage
|
from image.sub_image import SubImageExtract
|
||||||
from rbm.matrix import np
|
from rbm.matrix import np
|
||||||
|
|
||||||
|
|
||||||
@@ -8,7 +8,7 @@ if __name__ == "__main__":
|
|||||||
w = 8
|
w = 8
|
||||||
h = 8
|
h = 8
|
||||||
img_rbb = np.reshape(np.linspace(1, n*c*w*h, num=n*c*w*h, dtype=np.float64), (n, c, w, h))
|
img_rbb = np.reshape(np.linspace(1, n*c*w*h, num=n*c*w*h, dtype=np.float64), (n, c, w, h))
|
||||||
sub = SubImage(4, 4, 1, 1)
|
sub = SubImageExtract(4, 4, 1, 1)
|
||||||
sub(img_rbb, 3)
|
sub(img_rbb, 3)
|
||||||
|
|
||||||
img_gray = np.reshape(np.linspace(1, n*w*h, num=n*w*h, dtype=np.float64), (n, w, h))
|
img_gray = np.reshape(np.linspace(1, n*w*h, num=n*w*h, dtype=np.float64), (n, w, h))
|
||||||
|
|||||||
Reference in New Issue
Block a user