【问题标题】:how to implement tensorflow's next_batch for own data如何为自己的数据实现tensorflow的next_batch
【发布时间】:2017-04-21 01:06:21
【问题描述】:

tensorflow MNIST tutorial 中,mnist.train.next_batch(100) 函数非常方便。我现在正在尝试自己实现一个简单的分类。我在一个 numpy 数组中有我的训练数据。我怎样才能为我自己的数据实现类似的功能来给我下一批?

sess = tf.InteractiveSession()
tf.global_variables_initializer().run()
Xtr, Ytr = loadData()
for it in range(1000):
    batch_x = Xtr.next_batch(100)
    batch_y = Ytr.next_batch(100)

【问题讨论】:

    标签: python numpy neural-network tensorflow classification


    【解决方案1】:

    您发布的链接说:“我们从我们的训练集中获得了一个包含一百个随机数据点的“批次””。在我的示例中,我使用了一个全局函数(不是您示例中的方法),因此语法会有所不同。

    在我的函数中,您需要传递所需的样本数量和数据数组。

    这是正确的代码,可确保样本具有正确的标签:

    import numpy as np
    
    def next_batch(num, data, labels):
        '''
        Return a total of `num` random samples and labels. 
        '''
        idx = np.arange(0 , len(data))
        np.random.shuffle(idx)
        idx = idx[:num]
        data_shuffle = [data[ i] for i in idx]
        labels_shuffle = [labels[ i] for i in idx]
    
        return np.asarray(data_shuffle), np.asarray(labels_shuffle)
    
    Xtr, Ytr = np.arange(0, 10), np.arange(0, 100).reshape(10, 10)
    print(Xtr)
    print(Ytr)
    
    Xtr, Ytr = next_batch(5, Xtr, Ytr)
    print('\n5 random samples')
    print(Xtr)
    print(Ytr)
    

    然后进行演示:

    [0 1 2 3 4 5 6 7 8 9]
    [[ 0  1  2  3  4  5  6  7  8  9]
     [10 11 12 13 14 15 16 17 18 19]
     [20 21 22 23 24 25 26 27 28 29]
     [30 31 32 33 34 35 36 37 38 39]
     [40 41 42 43 44 45 46 47 48 49]
     [50 51 52 53 54 55 56 57 58 59]
     [60 61 62 63 64 65 66 67 68 69]
     [70 71 72 73 74 75 76 77 78 79]
     [80 81 82 83 84 85 86 87 88 89]
     [90 91 92 93 94 95 96 97 98 99]]
    
    5 random samples
    [9 1 5 6 7]
    [[90 91 92 93 94 95 96 97 98 99]
     [10 11 12 13 14 15 16 17 18 19]
     [50 51 52 53 54 55 56 57 58 59]
     [60 61 62 63 64 65 66 67 68 69]
     [70 71 72 73 74 75 76 77 78 79]]
    

    【讨论】:

    • 我相信这不会像用户期望的那样工作。输入 Xtr 和输出 Ytr 之间存在 1:1 的相关性。随机化是针对每个单独进行的。相反,应该选择一组随机值,​​然后将其应用于两组。
    • @edo 你可以用data[idx] 代替[data[ i] for i in idx],这样你就不会从ndarrays 跳到lists 再跳回ndarrays。
    【解决方案2】:

    为了对每个 mini-batch 进行混洗和采样,还应考虑在当前 epoch 内是否选择了样本的状态。这是一个使用上述答案中的数据的实现。

    import numpy as np 
    
    class Dataset:
    
    def __init__(self,data):
        self._index_in_epoch = 0
        self._epochs_completed = 0
        self._data = data
        self._num_examples = data.shape[0]
        pass
    
    
    @property
    def data(self):
        return self._data
    
    def next_batch(self,batch_size,shuffle = True):
        start = self._index_in_epoch
        if start == 0 and self._epochs_completed == 0:
            idx = np.arange(0, self._num_examples)  # get all possible indexes
            np.random.shuffle(idx)  # shuffle indexe
            self._data = self.data[idx]  # get list of `num` random samples
    
        # go to the next batch
        if start + batch_size > self._num_examples:
            self._epochs_completed += 1
            rest_num_examples = self._num_examples - start
            data_rest_part = self.data[start:self._num_examples]
            idx0 = np.arange(0, self._num_examples)  # get all possible indexes
            np.random.shuffle(idx0)  # shuffle indexes
            self._data = self.data[idx0]  # get list of `num` random samples
    
            start = 0
            self._index_in_epoch = batch_size - rest_num_examples #avoid the case where the #sample != integar times of batch_size
            end =  self._index_in_epoch  
            data_new_part =  self._data[start:end]  
            return np.concatenate((data_rest_part, data_new_part), axis=0)
        else:
            self._index_in_epoch += batch_size
            end = self._index_in_epoch
            return self._data[start:end]
    
    dataset = Dataset(np.arange(0, 10))
    for i in range(10):
        print(dataset.next_batch(5))
    

    输出是:

    [2 8 6 3 4]
    [1 5 9 0 7]
    [1 7 3 0 8]
    [2 6 5 9 4]
    [1 0 4 8 3]
    [7 6 2 9 5]
    [9 5 4 6 2]
    [0 1 8 7 3]
    [9 7 8 1 6]
    [3 5 2 4 0]
    

    第一个和第二个(第 3 个和第 4 个,...)小批量对应一个完整的 epoch..

    【讨论】:

      【解决方案3】:

      我使用 Anaconda 和 Jupyter。 在 Jupyter 中,如果你运行 ?mnist,你会得到: File: c:\programdata\anaconda3\lib\site-packages\tensorflow\contrib\learn\python\learn\datasets\base.py Docstring: Datasets(train, validation, test)

      在文件夹datesets 中,您将找到mnist.py,其中包含包括next_batch 在内的所有方法。

      【讨论】:

        【解决方案4】:

        上面标记的答案我用那个算法尝试了算法我没有得到结果,所以我在 kaggle 上搜索,我看到了非常棒的算法,效果非常好。最好的结果试试这个。 在下面的算法中**全局变量采用您在上面声明的输入数据集。**

        epochs_completed = 0
        index_in_epoch = 0
        num_examples = X_train.shape[0]
            # for splitting out batches of data
        def next_batch(batch_size):
        
            global X_train
            global y_train
            global index_in_epoch
            global epochs_completed
        
            start = index_in_epoch
            index_in_epoch += batch_size
        
            # when all trainig data have been already used, it is reorder randomly    
            if index_in_epoch > num_examples:
                # finished epoch
                epochs_completed += 1
                # shuffle the data
                perm = np.arange(num_examples)
                np.random.shuffle(perm)
                X_train = X_train[perm]
                y_train = y_train[perm]
                # start next epoch
                start = 0
                index_in_epoch = batch_size
                assert batch_size <= num_examples
            end = index_in_epoch
            return X_train[start:end], y_train[start:end]
        

        【讨论】:

          【解决方案5】:

          如果您不想在 tensorflow 会话运行中出现形状不匹配错误 然后使用下面的函数而不是上面第一个解决方案中提供的函数 (https://stackoverflow.com/a/40995666/7748451) -

          def next_batch(num, data, labels):
          
              '''
              Return a total of `num` random samples and labels. 
              '''
              idx = np.arange(0 , len(data))
              np.random.shuffle(idx)
              idx = idx[:num]
              data_shuffle = data[idx]
              labels_shuffle = labels[idx]
              labels_shuffle = np.asarray(labels_shuffle.values.reshape(len(labels_shuffle), 1))
          
              return data_shuffle, labels_shuffle
          

          【讨论】:

            【解决方案6】:

            又一个实现:

            from typing import Tuple
            import numpy as np
            
            class BatchMaker(object):
                def __init__(self, feat: np.array, lab: np.array) -> None:
                    if len(feat) != len(lab):
                        raise ValueError("Expected feat and lab to have the same number of samples")
                    self.feat = feat
                    self.lab = lab
                    self.indexes = np.arange(len(feat))
                    np.random.shuffle(self.indexes)
                    self.pos = 0
            
                # "BatchMaker, BatchMaker, make me a batch..."
                def next_batch(self, batch_size: int) -> Tuple[np.array, np.array]:
                    if self.pos + batch_size > len(self.feat):
                        np.random.shuffle(self.indexes)
                        self.pos = 0
                    batch_indexes = self.indexes[self.pos: self.pos + batch_size]
                    self.pos += batch_size
                    return self.feat[batch_indexes], self.lab[batch_indexes]
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2017-11-17
              • 2017-09-08
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多