1.翻转图像和关键点

```def flip_img_and_keypoints(img: np.ndarray, kpts:
Sequence[Sequence[int]]):
img = np.fliplr(img)
h, w, *_ = img.shape
kpts = [(y, w - x) for y, x in kpts]
return img, kpts```

```image = np.ones((10, 10), dtype=np.float32)
kpts = [(0, 1), (2, 2)]
image_flipped, kpts_flipped = flip_img_and_keypoints(image, kpts)

img1 = image.copy()
for y, x in kpts:
img1[y, x] = 0
img2 = image_flipped.copy()
for y, x in kpts_flipped:
img2[y, x] = 0

_ = plt.imshow(np.hstack((img1, img2)))```

```image = np.ones((10, 10), dtype=np.float32)
kpts = [(0, 0), (1, 1)]
image_flipped, kpts_flipped = flip_img_and_keypoints(image, kpts)

img1 = image.copy()
for y, x in kpts:
img1[y, x] = 0
img2 = image_flipped.copy()
for y, x in kpts_flipped:
img2[y, x] = 0
-------------------------------------------------------------------- -------
IndexError
Traceback (most recent call last)
<ipython-input-5-997162463eae> in <module>
8 img2 = image_flipped.copy()
9 for y, x in kpts_flipped:
---> 10 img2[y, x] = 0
IndexError: index 10 is out of bounds for axis 1 with size 10```

```def flip_img_and_keypoints(img: np.ndarray, kpts: Sequence[Sequence[int]]):
img = np.fliplr(img)
h, w, *_ = img.shape
kpts = [(y, w - x - 1) for y, x in kpts]
return img, kpts```

2.继续谈谈关键点

```kpts = [
(20, 20), # left pinky
(20, 200), # right pinky
...
]```

3.自定义损失函数

```def iou_continuous_loss(y_pred, y_true):
eps = 1e-6

def _sum(x):
return x.sum(-1).sum(-1)

numerator = (_sum(y_true * y_pred) + eps)
denominator = (_sum(y_true ** 2) + _sum(y_pred ** 2) -
_sum(y_true * y_pred) + eps)
return (numerator / denominator).mean()```

```In [3]: ones = np.ones((1, 3, 10, 10))
...: x1 = iou_continuous_loss(ones * 0.01, ones)
...: x2 = iou_continuous_loss(ones * 0.99, ones)

In [4]: x1, x2
Out[4]: (0.010099999897990103, 0.9998990001020204)```

```v> def iou_continuous(y_pred, y_true):
eps = 1e-6

def _sum(x):
return x.sum(-1).sum(-1)

numerator = (_sum(y_true * y_pred) + eps)
denominator = (_sum(y_true ** 2) + _sum(y_pred ** 2)
- _sum(y_true * y_pred) + eps)
return (numerator / denominator).mean()

def iou_continuous_loss(y_pred, y_true):
return 1 - iou_continuous(y_pred, y_true)```

4.使用 Pytorch

```from ceevee.base import AbstractPredictor

class MySuperPredictor(AbstractPredictor):
def __init__(self, weights_path: str, ):
super().__init__()

def process(self, x, *kw):
res = self.model(x)
return res

@staticmethod
model = ModelClass()
return model```

```In [4]: model = nn.Sequential(
...: nn.Linear(10, 10),
..: nn.Dropout(.5)
...: )
...:
...: traced_model = torch.jit.trace(model.eval(), torch.rand(10))

# No more warnings!```

5.复制粘贴问题

```v> def make_dataloaders(train_cfg, val_cfg, batch_size):
train = Dataset.from_config(train_cfg)
val = Dataset.from_config(val_cfg)
shared_params = {'batch_size': batch_size, 'shuffle': True,
'num_workers': cpu_count()}
return train, val```

```#
https://github.com/albu/albumentations/blob/0.3.0/albumentations/aug mentations/transforms.py
def apply_to_keypoint(self, keypoint, crop_height=0, crop_width=0, h_start=0, w_start=  0, rows=0, cols=0, **params):
keypoint = F.keypoint_random_crop(keypoint, crop_height, crop_width, h_start, w_start, rows, cols)
scale_x = self.width / crop_height
scale_y = self.height / crop_height
keypoint = F.keypoint_scale(keypoint, scale_x, scale_y) return keypoint```

```datasets = []

data_a = get_dataset(MyDataset(config['dataset_a']), config['shared_param'], param_a) datasets.append(data_a)
data_b = get_dataset(MyDataset(config['dataset_b']), config['shared_param'], param_b) datasets.append(data_b)```

```datasets = []
for name, param in zip(('dataset_a', 'dataset_b'), (param_a, param_b), ):
datasets.append(get_dataset(MyDataset(config[name]), config['shared_param'], param))```

6.合适的数据类型

```def add_noise(img: np.ndarray) -> np.ndarray:
return img.astype('uint8')```

```def add_noise(img: np.ndarray) -> np.ndarray:
return np.clip(img, 0, 255).astype('uint8')

7.打字错误

```from tqdm import tqdm

class GridPredictor:
""" This class can be used to predict a segmentation mask for the big image when you have GPU memory limitation """
def __init__(self, predictor: AbstractPredictor, size: int, stride: Optional[int] = None):               self.predictor = predictor
self.size = size
self.stride = stride if stride is not None else size // 2

def __call__(self, x: np.ndarray):
h, w, _ = x.shape
mask = np.zeros((h, w, 1), dtype='float32')

for i in tqdm(range(0, h - 1, self.stride)):
for j in range(0, w - 1, self.stride):
a, b, c, d = i, min(h, i + self.size), j, min(w, j + self.size)
patch = x[a:b, c:d, :]
mask[a:b, c:d, :] += np.expand_dims(self.predictor(patch), -1) weights[a:b, c:d, :] = 1

```class Model(nn.Module):
def forward(self, x):
return x.mean(axis=-1)

model = Model()
grid_predictor = GridPredictor(model, size=128, stride=64)

simple_pred = np.expand_dims(model(img), -1)
grid_pred = grid_predictor(img)
np.testing.assert_allclose(simple_pred, grid_pred, atol=.001)```

```def __call__(self, x: np.ndarray):
h, w, _ = x.shape
mask = np.zeros((h, w, 1), dtype='float32')

for i in tqdm(range(0, h - 1, self.stride)):
for j in range(0, w - 1, self.stride): a, b, c, d = i, min(h, i + self.size), j, min(w, j + self.size)
patch = x[a:b, c:d, :]
mask[a:b, c:d, :] += np.expand_dims(self.predictor(patch), -1)
weights[a:b, c:d, :] += 1

8.ImageNet 规范化

```from albumentations import Normalize

norm = Normalize()

mask = np.expand_dims(mask, -1) # shape (64, 64) -> shape (64, 64, 1)

def img_to_batch(x):
x = np.transpose(x, (2, 0, 1)).astype('float32')

criterion = F.binary_cross_entropy```

```model_a = UNet(3, 1)
losses = []

for t in tqdm(range(20)):
losses.append(loss.item())
loss.backward()
optimizer.step()

_ = plt.plot(losses)```

```model_b = UNet(3, 1)
losses = []

for t in tqdm(range(20)):
loss = criterion(model_b(img), mask / 255.)
losses.append(loss.item())
loss.backward()
optimizer.step()

_ = plt.plot(losses)```