Pourquoi tester le code d'article dans l'apprentissage automatique. Analysons un exemple

Dans cet article, je vais vous montrer avec un exemple comment l'inattention au code peut conduire à des résultats incorrects dans l'exploration de données. 





Il existe un excellent cours [1] où les étudiants apprennent à faire de la recherche sur l'apprentissage automatique. À la fin du semestre, les étudiants préparent un article. Lors des conférences, on leur dit simultanément comment le faire. En règle générale, la préparation d'un article implique la réalisation d'une expérience avec des données. Sur la base des résultats du semestre, plusieurs articles sont déjà prêts à être soumis à la revue.





Ainsi, dans le projet MLDev, nous aidons à créer un référentiel de modèles pour les étudiants de ce cours. Un tel modèle, ou en d'autres termes, un modèle, vous permettra de commencer à travailler sur un article plus rapidement et d'étudier moins les différents outils nécessaires.





Pendant que je parcourais les travaux du printemps 2020, je me suis intéressé à un graphe inhabituel dans l'ouvrage «Analyse des propriétés d'un ensemble de modèles localement approximatifs» [2]. Le graphique avec les résultats de l'expérience montre clairement un écart dans les valeurs de la dépendance présentée. Mais en fonction du choix des données initiales et des propriétés de cette dépendance, il ne devrait pas y avoir de vide à cet endroit.





Il est curieux de vérifier pourquoi un résultat aussi inattendu a été obtenu dans le travail.





Répéter l'expérience

, . , , . . , .





, , . , . .





. , , [2]. . .





  Google Colab . MixtureLib



GitHub [3]. MixtureLib



. . , .









!git clone https://github.com/andriygav/MixtureLib.git
!python3 -m pip install MixtureLib/src/.
from mixturelib.localmodels import EachModelLinear
from mixturelib.hypermodels import HyperExpertNN, HyperModelDirichlet
from mixturelib.mixture import MixtureEM
      
      



. , . 





correlations = []
sigmas = [0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,
         1.0,0.03,0.04,0.05,0.06,0.07,0.08,0.09,
         0.15,0.25,0.35,0.45,0.55,0.65,0.75,0.85,
         0.95,0.11,0.12,0.13,0.14,0.15,0.22,0.27,
         0.32,0.37,0.42,0.47,0.52,0.57,0.62,0.67,
         0.72,0.77,0.82,0.87,0.92,0.97]
      
      



, EachModelLinear



, . . MixtureEM



HyperNetEM



, . , . , .





torch.random.manualseed(42)
first_model = EachModelLinear(input_dim=2)
second_model = EachModelLinear(input_dim=2)
list_of_models = [firstmodel, second_model]

HpMd = HyperExpertNN(inputdim=2, hiddendim=5,outputdim=2, epochs=1000)
mixture = MixtureEM(HyperParameters={'beta': 1.},
                    HyperModel=HpMd,
                    ListOfModels=listofmodels,
                    modeltype='sample')
      
      



. . 





for i, sigma in enumerate(sigmas):
    # 
    x1 = np.random.normal(0, 1, (200, 1))
    x2 = np.random.normal(0, 1, (200, 1))
    y1 = np.array([f1(x) for x in x1])
    y2 = np.array([f2(x) for x in x2])
    s1 = np.random.normal(0, sigma, 200).reshape((200, 1))
    s2 = np.random.normal(0, sigma, 200).reshape((200, 1))
    X1 = np.hstack([x1, s1]) 
    X2 = np.hstack([s2, x2])
    X = np.vstack([X1, X2])
    Y = np.hstack([y1, y2])
    realsecondw = np.array([[10.], [0.]])
    realfirstw = np.array([[0.], [50.]])
    Xtr = torch.FloatTensor(X)
    Ytr = torch.FloatTensor(Y).view([-1,1])

    # 
    # …
      
      







, . . .





for i, sigma in enumerate(sigmas):
    # 
    # ... 
    
    # 
    torch.random.manual_seed(42)
    mixture.fit(X_tr, Y_tr)
    predicted_first_w = mixture.ListOfModels[0].W.numpy()
    predicted_second_w = mixture.ListOfModels[1].W.numpy()
    weights = []
    weights.append([predicted_first_w[0][0], predicted_first_w[1][0]])
    weights.append([predicted_second_w[0][0], predicted_second_w[1][0]])
    #     ,  
    Y1 = X.dot(weights[0])
    Y2 = X.dot(weights[1])
    correlations.append(cor_Pearson(Y1, Y2))

      
      



, . , . , . , , . , .





Calcul sans changement vers l'avant sur la liste sigma
Calcul à rebours sur une liste sigma

, , . . , .





. , , , . , , , . , .





fit()



MixtureEM



. , , . . .





? fit()



. MixtureLib



, fit()



. .





, fit()



fit()



scikit-learn



, . partial_fit()



(. ).





, , . . , .





, . fit()



.





, .





  • , , . , .





  • , . , .





  • . , , ?





  • , , . , .





  • , .





[1] “ ”, - https://m1p.org





[2] - https://github.com/Intelligent-Systems-Phystech/2020_Project-51





[3] MixtureLib



- https://github.com/andriygav/MixtureLib





[4] - https://colab.research.google.com/drive/1DZoJN32EpTZVSi2N3BduRCRf-ZST8snP#scrollTo=1JopTLX4eMnX





PS Bien sûr, nous avons contacté et discuté de ce que nous avons trouvé avec les auteurs de l'article et la bibliothèque MixtureLib



. L'erreur a été confirmée. L'article a été rédigé en mars, donc en décembre, il est déjà difficile de reconstituer exactement comment le graphique original a été obtenu et comment l'expérience a été menée. Ensuite, vous pouvez deviner si l'expérience a été réalisée en plusieurs parties. Surtout si vous faites attention au manque de graphiques dans le cahier d'origine et à cette liste de sigma:





sigmas = [0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,
          1.0,0.03,0.04,0.05,0.06,0.07,0.08,0.09,
          0.15,0.25,0.35,0.45,0.55,0.65,0.75,0.85,
          0.95,0.11,0.12,0.13,0.14,0.15,0.22,0.27,
          0.32,0.37,0.42,0.47,0.52,0.57,0.62,0.67,
          0.72,0.77,0.82,0.87,0.92,0.97]
      
      










All Articles