SummitKwan / transparent_latent_gan

Use supervised learning to illuminate the latent space of GAN for controlled generation and edit
MIT License
1.97k stars 362 forks source link

Should Linear Classifier be replace by a multilabel classifier? #25

Closed shartoo closed 5 years ago

shartoo commented 5 years ago

As shown in demo ,many attribution of a generated image can be adjusted. When preparing my own dataset,such as Celeba-HQ which every sample has 40 attributions(Gray_Hair,Heavy_Makeup,High_Cheekbones,Male...).This is obviously a multilabel classify problem, likewise with current repo ,simple LinearRegression seems work at th begining but fails as dataset size increase(from 4000 to 8000 image samples). Some of my result comes from LinearRegression model trained on 4000 image samples of Celeba-HQ

ori_00036

Eyeglasses_00036_old

No_Beard_00036_old

Smiling_00036

I want to change some other attribution but all failed

shartoo commented 5 years ago

The above image are generated with the help of feature_axis.py and script_label_regression.py without any change combined with StyleGAN with a dataset of 4000 samples.As image samples grown to 8000,a newer model was trained ,but i could't change any attribution any more . I thought this must be caused by sth with data itself like class imblance and so on , so tried a multilabel classify model accoring to find_feature_axis method in feature_axis.py

def find_feature_axis_multilabel(z, y):
    """
        a  multilabel classify model
    :param z: vectors in the latent space, shape=(num_samples, num_latent_vector_dimension)
    :param y: feature vectors, shape=(num_samples, num_features)
    :return: feature vectors, shape = (num_latent_vector_dimension, num_features)
    """
    mb = MultiLabelBinarizer()
    y = mb.fit_transform(y)
    clf = OneVsRestClassifier(LogisticRegression(), n_jobs=-1)
    clf.fit(z, y)
    # training set result
    y_predicted = clf.predict(z)
    # report
    print(metrics.classification_report(y,y_predicted))
    accuracy = np.mean(y_predicted == y)
    print("model accuracy ",accuracy)
    return clf.coef_.transpose()

and error occur

File "script_label_regression.py", line 99, in <module>
    train_direction_model(z_arr,y_arr,path_celeba_att,path_feature_direction)
  File "script_label_regression.py", line 54, in train_direction_model
    multilabel = feature_axis.find_feature_axis_multilabel(z, y)
  File "/home/xiatao/work/swap_face/stylegan-encoder/feature_axis.py", line 57, in find_feature_axis_multilabel
    return clf.coef_.transpose()
  File "/usr/local/anaconda3/lib/python3.6/site-packages/sklearn/multiclass.py", line 389, in coef_
    "Base estimator doesn't have a coef_ attribute.")
AttributeError: Base estimator doesn't have a coef_ attribute.

I can't return the coef of this multilabel classify model.

shartoo commented 5 years ago

Effect of trump

original trump

ori_trump

Smiling

Smiling_trump

Eyeglasses

Eyeglasses_trump

Bushy Eyebrows

Bushy_Eyebrows_trump

SummitKwan commented 5 years ago

Hi, first, thanks for testing the code and try with different dataset. It seems to me that the OneVsAll classier is not a good strategy since for every label, there are only two classes, i.e., every labels simply requires a binary classifier. The classification of any label can be independent. I would suggest try to see if class imbalance is bad or not in this case.

shartoo commented 5 years ago

SVM model works now,i can adjust most attribution on faces.

clf = OneVsRestClassifier(SVC(kernel='linear',class_weight="balanced"), n_jobs=-1)
clf.fit(z, y)
shartoo commented 5 years ago

Result 1 2 3 4 5-1 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23png

SummitKwan commented 5 years ago

Looks super encouraging! Thanks for sharing