Skip to content

Instantly share code, notes, and snippets.

@algonacci
Created October 7, 2024 08:38
Show Gist options
  • Save algonacci/bc505e47307ccc35a16095077d22a255 to your computer and use it in GitHub Desktop.
Save algonacci/bc505e47307ccc35a16095077d22a255 to your computer and use it in GitHub Desktop.
Fashion GAN

Step 1: Data Ingestion

Using Google Cloud Storage to store raw data from multiple sources

from google.cloud import storage
from google.cloud import bigquery

def upload_to_gcs(bucket_name, file_name, data):
    client = storage.Client()
    bucket = client.get_bucket(bucket_name)
    blob = bucket.blob(file_name)
    blob.upload_from_string(data)
    print(f"File {file_name} uploaded to {bucket_name}")

Sample ingestion

ecommerce_data = "ecommerce_sales.csv"
social_media_data = "social_trends.json"
bucket_name = "fashion-data-lake"
upload_to_gcs(bucket_name, ecommerce_data, ecommerce_data)
upload_to_gcs(bucket_name, social_media_data, social_media_data)

Step 2: Data Preprocessing

Using BigQuery to preprocess structured data, clean missing values, and normalize

def preprocess_data():
    client = bigquery.Client()
    query = """
        SELECT
            product_id,
            sales,
            IFNULL(social_trends_score, 0) as trend_score,
            (sales - MIN(sales) OVER()) / (MAX(sales) OVER() - MIN(sales) OVER()) as normalized_sales
        FROM
            `project.dataset.sales_data`
        WHERE
            sales IS NOT NULL
    """
    job = client.query(query)
    result = job.result()  # Waits for query to finish
    return result

processed_data = preprocess_data()

Step 3: GAN Training with TensorFlow

import tensorflow as tf
from tensorflow.keras import layers

# GAN Generator Model
def build_generator():
    model = tf.keras.Sequential()
    model.add(layers.Dense(128, input_dim=100)) #please fill in the empty value
    model.add(layers.LeakyReLU(0.2))
    model.add(layers.BatchNormalization())
    model.add(layers.Dense(256)) #please fill in the empty value
    model.add(layers.LeakyReLU(0.2)) #please fill in the empty value
    model.add(layers.BatchNormalization())
    model.add(layers.Dense(512)) #please fill in the empty value
    model.add(layers.LeakyReLU(0.2)#please fill in the empty value
    model.add(layers.BatchNormalization())
    model.add(layers.Dense(784, activation='tanh'))  # Fashion design as 28x28 image
    model.add(layers.Reshape((28, 28, 1)))  # Reshape to 28x28x1 (grayscale image)

    return model

# GAN Discriminator Model
def build_discriminator():
    model = tf.keras.Sequential()
    model.add(layers.Flatten(input_shape=(28, 28, 1)))  # Flatten the input image
    model.add(layers.Dense(512)) #please fill in the empty value
    model.add(layers.LeakyReLU(0.2))
    model.add(layers.Dense(256))
    model.add(layers.LeakyReLU(0.2))
    model.add(layers.Dense(1, activation='sigmoid'))
    return model

# Compile GAN
def compile_gan(generator, discriminator):
    discriminator.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
    discriminator.trainable = False
    gan_input =  tf.keras.layers.Input(shape=(100,)) #please fill in the empty value
    generated_image = generator(gan_input)
    gan_output = discriminator(generated_image)
    gan = tf.keras.Model(gan_input, gan_output)
    gan.compile(loss='binary_crossentropy', optimizer='adam')
    return gan

# Train GAN
def train_gan(generator, discriminator, gan, epochs=1000, batch_size=128):
    for epoch in range(epochs):
        noise = tf.random.normal([batch_size, 100])
        generated_images = generator.predict(noise)
        real_images = processed_data.sample(batch_size)
        labels_real = tf.ones((batch_size, 1)) #please fill in the empty value
        labels_fake = tf.zeros((batch_size, 1)) #please fill in the empty value

        d_loss_real = discriminator.train_on_batch(real_images, labels_real) #please fill in the empty value
        d_loss_fake = discriminator.train_on_batch(generated_images, labels_fake) #please fill in the empty value

        noise = tf.random.normal([batch_size, 100])
        g_loss = gan.train_on_batch(noise, tf.ones((batch_size, 1)))

        if epoch % 100 == 0:
            print(f"Epoch {epoch}, D Loss Real: {d_loss_real}, D Loss Fake: {d_loss_fake}, G Loss: {g_loss}")

Build and train the GAN

generator = build_generator()
discriminator = build_discriminator()
gan = compile_gan(generator, discriminator) #please fill in the empty value
train_gan(generator, discriminator, gan)

Step 4: Model Deployment using Vertex AI

from google.cloud import aiplatform

def deploy_model_to_vertex_ai(model_artifact, endpoint_name):
    aiplatform.init()
    model = aiplatform.Model.upload(display_name="fashion-gan-model", artifact_uri=model_artifact)
    endpoint = model.deploy(machine_type="n1-standard-4", endpoint_name=endpoint_name)
    return endpoint

endpoint = deploy_model_to_vertex_ai("gs://fashion-model-bucket/gan_model", "fashion-gan-endpoint")

# Step 5: Real-Time Inference
import numpy as np

def generate_fashion_design():
    noise = np.random.normal(0, 1, (1, 100))
    design = generator.predict(noise)
    print(f"Generated fashion design: {design}")
    return design

generate_fashion_design()

Kubernetes Auto-Scaling

Please create a simple Kubernetes YAML deployment for auto-scaling the GAN inference system and expose to 8080

apiVersion: apps/v1
kind: Deployment
metadata:
  name: gan-inference-deployment
spec:
  replicas: 10
  selector:
    matchLabels:
      app: gan-inference
  template:
    metadata:
      labels:
        app: gan-inference
    spec:
      containers:
        - name: gan-inference-container
          image: gcr.io/fashion-iykra/gan-inference:latest
          ports:
            - containerPort: 8080
          resources:
            requests:
              cpu: "2"
              memory: "4Gi"
            limits:
              cpu: "4"
              memory: "8Gi"
          env:
            - name: ENDPOINT_URL
              value: "https://api.fashion-iykra.com"
            - name: PORT
              value: "8080"

---
apiVersion: v1
kind: Service
metadata:
  name: gan-inference-service
spec:
  selector:
    app: gan-inference
  ports:
    - protocol: TCP
      port: 8080
      targetPort: 8080
  type: LoadBalancer

---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: gan-inference-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: gan-inference-deployment
  minReplicas: 1
  maxReplicas: 10
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 60
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment