N-Shot Learning：用最少的数据训练最多的模型

1.

N-Shot Learning

1-1 为什么需要N-Shot？

1-2 Zero-Shot learning

• Learning to Compare: Relation Network for Few-Shot Learning（https://arxiv.org/pdf/1711.06025v2.pdf）
• Learning Deep Representations of Fine-Grained Visual Descriptions（https://arxiv.org/pdf/1605.05395v1.pdf）
• Improving zero-shot learning by mitigating the hubness problem（https://arxiv.org/abs/1412.6568v3）

1-3 One-Shot Learning

• Model-Agnostic Meta-Learning for Fast Adaptation of Deep Networks（https://arxiv.org/pdf/1703.03400v3.pdf）
• One-shot Learning with Memory-Augmented Neural Networks（https://arxiv.org/pdf/1605.06065v1.pdf）
• Prototypical Networks for Few-shot Learning（https://arxiv.org/pdf/1703.05175v2.pdf）

1-4 小样本学习

2.

• 深度学习的课程：https://blog.floydhub.com/best-deep-learning-courses-updated-for-2019/.
• 深度学习书籍：https://blog.floydhub.com/best-deep-learning-books-updated-for-2019/.
• 快速学习和应用 Building Your First ConvNethttps://blog.floydhub.com/building-your-first-convnet/

2-5 数据集概览

Omniglot数据集中的部分示例（图源：https://github.com/brendenlake/omniglot）

```class Net(nn.Module):
"""
Image2Vector CNN which takes the image of dimension (28x28x3) and return column vector length 64
"""
def sub_block(self, in_channels, out_channels=64, kernel_size=3):
block = torch.nn.Sequential(
torch.nn.BatchNorm2d(out_channels),
torch.nn.ReLU()
torch.nn.MaxPool2d(kernel_size=2))
return block
def __init__(self):
super(Net, self).__init__()
self.convnet1 = self.sub_block(3)
self.convnet2 = self.sub_block(64)
self.convnet3 = self.sub_block(64)
self.convnet4 = self.sub_block(64)
def forward(self, x):
x = self.convnet1(x)
x = self.convnet2(x)
x = self.convnet3(x)
x = self.convnet4(x)
x = torch.flatten(x, start_dim=1)
return x```

```class PrototypicalNet(nn.Module):
def __init__(self, use_gpu=False):
super(PrototypicalNet, self).__init__()
self.f = Net()
self.gpu = use_gpu        if self.gpu:
self.f = self.f.cuda()

def forward(self, datax, datay, Ns,Nc, Nq, total_classes):
"""
Implementation of one episode in Prototypical Net
datax: Training images
datay: Corresponding labels of datax
Nc: Number  of classes per episode
Ns: Number of support data per class
Nq:  Number of query data per class
total_classes: Total classes in training set
"""
k = total_classes.shape[0]
K = np.random.choice(total_classes, Nc, replace=False)
Query_x = torch.Tensor()
if(self.gpu):
Query_x = Query_x.cuda()
Query_y = []
Query_y_count = []
centroid_per_class  = {}
class_label = {}
label_encoding = 0
for cls in K:
S_cls, Q_cls = self.random_sample_cls(datax, datay, Ns, Nq, cls)
centroid_per_class[cls] = self.get_centroid(S_cls, Nc)
class_label[cls] = label_encoding
label_encoding += 1
Query_x = torch.cat((Query_x, Q_cls), 0) # Joining all the query set together
Query_y += [cls]
Query_y_count += [Q_cls.shape[0]]
Query_y, Query_y_labels = self.get_query_y(Query_y, Query_y_count, class_label)
Query_x = self.get_query_x(Query_x, centroid_per_class, Query_y_labels)
return Query_x, Query_y
def random_sample_cls(self, datax, datay, Ns, Nq, cls):
"""
Randomly samples Ns examples as support set and Nq as Query set
"""
data = datax[(datay == cls).nonzero()]
perm = torch.randperm(data.shape[0])
idx = perm[:Ns]
S_cls = data[idx]
idx = perm[Ns : Ns+Nq]
Q_cls = data[idx]
if self.gpu:
S_cls = S_cls.cuda()
Q_cls = Q_cls.cuda()
return S_cls, Q_cls
def get_centroid(self, S_cls, Nc):
"""
Returns a centroid vector of support set for a class
"""
def get_query_y(self, Qy, Qyc, class_label):
"""
Returns labeled representation of classes of Query set and a list of labels.
"""
labels = []
m = len(Qy)
for i in range(m):
labels += [Qy[i]] * Qyc[i]
labels = np.array(labels).reshape(len(labels), 1)
label_encoder = LabelEncoder()
Query_y = torch.Tensor(label_encoder.fit_transform(labels).astype(int)).long()
if self.gpu:
Query_y = Query_y.cuda()
Query_y_labels = np.unique(labels)
return Query_y, Query_y_labels
def get_centroid_matrix(self, centroid_per_class, Query_y_labels):
"""
Returns the centroid matrix where each column is a centroid of a class.
"""
centroid_matrix = torch.Tensor()
if(self.gpu):
centroid_matrix = centroid_matrix.cuda()
for label in Query_y_labels:
centroid_matrix = torch.cat((centroid_matrix, centroid_per_class[label]))
if self.gpu:
centroid_matrix = centroid_matrix.cuda()
return centroid_matrix
def get_query_x(self, Query_x, centroid_per_class, Query_y_labels):
"""
Returns distance matrix from each Query image to each centroid.
"""
centroid_matrix = self.get_centroid_matrix(centroid_per_class, Query_y_labels)
Query_x = self.f(Query_x)
m = Query_x.size(0)
n = centroid_matrix.size(0)
# The below expressions expand both the matrices such that they become compatible with each other in order to calculate L2 distance.
centroid_matrix = centroid_matrix.expand(m, centroid_matrix.size(0), centroid_matrix.size(1)) # Expanding centroid matrix to "m".
Query_matrix = Query_x.expand(n, Query_x.size(0), Query_x.size(1)).transpose(0,1) # Expanding Query matrix "n" times
Qx = torch.pairwise_distance(centroid_matrix.transpose(1,2), Query_matrix.transpose(1,2))
return Qx```

3.

• One Shot Learning with Siamese Networks using Keras（https://sorenbouma.github.io/blog/oneshot/）
• One-Shot Learning: Face Recognition using Siamese Neural Network（https://towardsdatascience.com/one-shot-learning-face-recognition-using-siamese-neural-network-a13dcf739e）
• Matching network official implementation（https://github.com/AntreasAntoniou/MatchingNetworks）
• Prototypical Network official implementation.（https://github.com/orobix/Prototypical-Networks-for-Few-shot-Learning-PyTorch）
• Meta-Learning for Semi-Supervised Few-Shot Classification（https://arxiv.org/abs/1803.00676）

4.

5.

via https://blog.floydhub.com/n-shot-learning/

0 条评论