keras-team / keras

Deep Learning for humans
http://keras.io/
Apache License 2.0
62.01k stars 19.48k forks source link

TypeError: add_weight() got multiple values for argument 'name' #16423

Closed jyyang621 closed 2 years ago

jyyang621 commented 2 years ago

Hi, I met a problem like this: image the build part is shown as below: image I don't know how can I fix the bug, please help me! ok, i will put the code

from keras.datasets import mnist  
import numpy as np  
np.random.seed(10)

from time import time
import numpy as np
import keras.backend as K
# from keras.engine.topology import Layer, InputSpec
from keras.layers import Layer, InputSpec
from keras.layers import Dense, Input
from keras.models import Model
# from keras.optimizers import SGD
from tensorflow.keras.optimizers import SGD
from keras import callbacks
from keras.initializers import VarianceScaling
from sklearn.cluster import KMeans
import metrics

def autoencoder(dims, act='relu', init='glorot_uniform'):
    """
    Fully connected auto-encoder model, symmetric.
    Arguments:
        dims: list of number of units in each layer of encoder. dims[0] is input dim, dims[-1] is units in hidden layer.
            The decoder is symmetric with encoder. So number of layers of the auto-encoder is 2*len(dims)-1
        act: activation, not applied to Input, Hidden and Output layers
    return:
        (ae_model, encoder_model), Model of autoencoder and model of encoder
    """
    n_stacks = len(dims) - 1
    # input
    input_img = Input(shape=(dims[0],), name='input')
    x = input_img
    # internal layers in encoder
    for i in range(n_stacks-1):
        x = Dense(dims[i + 1], activation=act, kernel_initializer=init, name='encoder_%d' % i)(x)

    # hidden layer
    encoded = Dense(dims[-1], kernel_initializer=init, name='encoder_%d' % (n_stacks - 1))(x)  
    # hidden layer, features are extracted from here

    x = encoded
    # internal layers in decoder
    for i in range(n_stacks-1, 0, -1):
        x = Dense(dims[i], activation=act, kernel_initializer=init, name='decoder_%d' % i)(x)

    # output
    x = Dense(dims[0], kernel_initializer=init, name='decoder_0')(x)
    decoded = x
    return Model(inputs=input_img, outputs=decoded, name='AE'), Model(inputs=input_img, outputs=encoded, name='encoder')

(x_train, y_train), (x_test, y_test) = mnist.load_data()

x = np.concatenate((x_train, x_test))
y = np.concatenate((y_train, y_test))
x = x.reshape((x.shape[0], -1))
x = np.divide(x, 255.)

n_clusters = len(np.unique(y))
# x.shape

# kmeans = KMeans(n_clusters=n_clusters, n_init=20, n_jobs=4)
kmeans = KMeans(n_clusters=n_clusters, n_init=20)
y_pred_kmeans = kmeans.fit_predict(x)

def accuracy(y_true, y_pred):
    """
    Calculate clustering accuracy. Require scikit-learn installed

    # Arguments
        y: true labels, numpy.array with shape `(n_samples,)`
        y_pred: predicted labels, numpy.array with shape `(n_samples,)`

    # Return
        accuracy, in [0,1]
    """
    y_true = y_true.astype(np.int64)
    assert y_pred.size == y_true.size
    D = max(y_pred.max(), y_true.max()) + 1
    w = np.zeros((D, D), dtype=np.int64)
    for i in range(y_pred.size):
        w[y_pred[i], y_true[i]] += 1
    # from sklearn.utils.linear_assignment_ import linear_assignment
    from scipy.optimize import linear_sum_assignment as linear_assignment
    ind = linear_assignment(w.max() - w)
    return sum([w[i, j] for i, j in ind]) * 1.0 / y_pred.size

dims = [x.shape[-1], 500, 500, 2000, 10]
init = VarianceScaling(scale=1. / 3., mode='fan_in',
                           distribution='uniform')
# pretrain_optimizer = SGD(lr=1, momentum=0.9)
pretrain_optimizer = SGD(learning_rate=1, momentum=0.9)
pretrain_epochs = 300
batch_size = 256
save_dir = './results'  # need a folder called results

autoencoder, encoder = autoencoder(dims, init=init)
autoencoder.compile(optimizer=pretrain_optimizer, loss='mse')
autoencoder.fit(x, x, batch_size=batch_size, epochs=pretrain_epochs) #, callbacks=cb)

autoencoder.save_weights(save_dir + '/ae_weights.h5')
autoencoder.load_weights(save_dir + '/ae_weights.h5')

class ClusteringLayer(Layer):
    """
    Clustering layer converts input sample (feature) to soft label, i.e. a vector that represents the probability of the
    sample belonging to each cluster. The probability is calculated with student's t-distribution.
    聚类层将输入样本(要素)转换为软标签,即表示属于每个聚类的样本。概率是用学生的 t 分布计算的。

    # Example
    model.add(ClusteringLayer(n_clusters=10))
```
# Arguments
    n_clusters: number of clusters.
    weights: list of Numpy array with shape `(n_clusters, n_features)` witch represents the initial cluster centers.
    alpha: degrees of freedom parameter in Student's t-distribution. Default to 1.0.
# Input shape
    2D tensor with shape: `(n_samples, n_features)`.
# Output shape
    2D tensor with shape: `(n_samples, n_clusters)`.
"""
def __init__(self, n_clusters, weights=None, alpha=1.0, **kwargs):
    if 'input_shape' not in kwargs and 'input_dim' in kwargs:
        kwargs['input_shape'] = (kwargs.pop('input_dim'),)
    super(ClusteringLayer, self).__init__(**kwargs)
    self.n_clusters = n_clusters
    self.alpha = alpha
    self.initial_weights = weights
    self.input_spec = InputSpec(ndim=2)

def build(self, input_shape):
    assert len(input_shape) == 2
    input_dim = input_shape[1]
    self.input_spec = InputSpec(dtype=K.floatx(), shape=(None, input_dim))
    self.clusters = self.add_weight((self.n_clusters, input_dim), initializer='glorot_uniform', name='clusters')
    if self.initial_weights is not None:
        self.set_weights(self.initial_weights)
        del self.initial_weights
    self.built = True

def call(self, inputs, **kwargs):
    """ student t-distribution, as same as used in t-SNE algorithm.
     Measure the similarity between embedded point z_i and centroid µ_j.
             q_ij = 1/(1+dist(x_i, µ_j)^2), then normalize it.
             q_ij can be interpreted as the probability of assigning sample i to cluster j.
             (i.e., a soft assignment)
    Arguments:
        inputs: the variable containing data, shape=(n_samples, n_features)
    Return:
        q: student's t-distribution, or soft labels for each sample. shape=(n_samples, n_clusters)
    """
    q = 1.0 / (1.0 + (K.sum(K.square(K.expand_dims(inputs, axis=1) - self.clusters), axis=2) / self.alpha))
    q **= (self.alpha + 1.0) / 2.0
    q = K.transpose(K.transpose(q) / K.sum(q, axis=1)) # Make sure each sample's 10 values add up to 1.
    return q

def compute_output_shape(self, input_shape):
    assert input_shape and len(input_shape) == 2
    return input_shape[0], self.n_clusters

def get_config(self):
    config = {'n_clusters': self.n_clusters}
    base_config = super(ClusteringLayer, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

clustering_layer = ClusteringLayer(n_clusters, name='clustering')(encoder.output)

clustering_layer = ClusteringLayer(n_clusters, name='clustering')(encoder.output) model = Model(inputs=encoder.input, outputs=clustering_layer) # wrong

sushreebarsa commented 2 years ago

@Yang621435 In order to expedite the trouble-shooting process, please provide a code snippet to reproduce the issue reported here. Thanks!

jyyang621 commented 2 years ago

@sushreebarsa had done, thanks

AshwinJay101 commented 2 years ago

The code snippet does not include imports and values for n_cluster etc

Can you please add that

sushreebarsa commented 2 years ago

@Yang621435 I tried to reproduce this issue with the provided code and faced different errors . In order to expedite the trouble-shooting process, please provide a complete code snippet to reproduce the issue reported here. Thanks!

jyyang621 commented 2 years ago

The code snippet does not include imports and values for n_cluster etc

Can you please add that

had done

jyyang621 commented 2 years ago

@Yang621435 I tried to reproduce this issue with the provided code and faced different errors . In order to expedite the trouble-shooting process, please provide a complete code snippet to reproduce the issue reported here. Thanks!

had done

sushreebarsa commented 2 years ago

@Yang621435 I tried to replicate the issue on colab using TF v2.8.0 and faced a different error .Could you please find the gist here and confirm the same? Thanks!

jyyang621 commented 2 years ago

@Yang621435 I tried to replicate the issue on colab using TF v2.8.0 and faced a different error .Could you please find the gist here and confirm the same? Thanks!

my TF version is 2.9.0 and could you tell me what error you met? I met some errors in the codes but I solved them, the code I put shouldn't have errors until the end

sushreebarsa commented 2 years ago

@Yang621435 Thank you for the quick update! I didn't face the TypeError either. Could you please move this issue to closed status if it is resolved for you ? Thanks!

google-ml-butler[bot] commented 2 years ago

This issue has been automatically marked as stale because it has no recent activity. It will be closed if no further activity occurs. Thank you.

google-ml-butler[bot] commented 2 years ago

Closing as stale. Please reopen if you'd like to work on this further.

google-ml-butler[bot] commented 2 years ago

Are you satisfied with the resolution of your issue? Yes No