Skip navigation

Category Archives: Exercise 5

chair-clustering

Above is an image of my Exercise 5.

==============================================================

Description:

This Processing applet was made to explore how machine learning can be used to cluster chairs into categories. The applet clusters images from a database I made of chairs designed by Verner Panton, Charles and Ray Eames, Le Corbusier, Pierre Jeanneret, Charlotte Perriand, Harry Bertoia, and Eero Saarinen. When the applet is ran, it clusters all of the chairs into categories.

==============================================================

Code:

import wekaizing.*;
import java.io.File;
import java.lang.Integer;
class digitImage {
int number;
PImage digit_image;
int[] pixeldata;
public digitImage(int image_size) {
pixeldata = new int[image_size*image_size];}
}
WekaData digits_data;
WekaClusterer clusterer;
digitImage[] digits;
int NUM_DIGITS = 100;
int TRAIN_IMAGE_SIZE = 20;
int NUM_CLUSTERS = 10;
int[] clusters;
PFont courier_font;
void setup() {
background(0);
size(1800,1200);
courier_font = loadFont(“CourierNew-12.vlw”);
textFont(courier_font, 15);
digits_data = new WekaData();
for (int i = 0; i < TRAIN_IMAGE_SIZE*TRAIN_IMAGE_SIZE; i++) {
digits_data.AddAttribute(Integer.toString(i));
}
loadDigits(“digits”);
clusterer = new WekaClusterer(WekaClusterer.EM);
clusters = clusterer.clusterData(digits_data,NUM_CLUSTERS);
print(“Training done”);
drawResults();
}
void loadDigits(String digitfolder) {
File digitfiles = new File(sketchPath, “data/” + digitfolder);
String[] files = digitfiles.list(filter);
if(files.length < NUM_DIGITS)
NUM_DIGITS = files.length;
digits = new digitImage[NUM_DIGITS];
String numbers[] = loadStrings(digitfolder + “/digits.txt”);
for (int i = 0; i<NUM_DIGITS ; i++) {
println(“Loading image ” + files[i]);
digits[i] = new digitImage(TRAIN_IMAGE_SIZE);
digits[i].digit_image = loadImage(“data/” + digitfolder + “/” + files[i]);
digits[i].number = Integer.valueOf(numbers[i]);
PImage resizedImg = loadImage(“data/” + digitfolder + “/” + files[i]);
resizedImg.resize(TRAIN_IMAGE_SIZE,TRAIN_IMAGE_SIZE);
resizedImg.loadPixels();
for (int j = 0; j < TRAIN_IMAGE_SIZE*TRAIN_IMAGE_SIZE; j++) {
digits[i].pixeldata[j] = resizedImg.pixels[j];
}
digits_data.InsertData(digits[i].pixeldata);
}
}
void drawResults() {
int imgx=0, imgy=0;
for (int j=0;j<NUM_CLUSTERS;j++)
{
for (int i = 0; i < digits.length; i++) {
if(clusters[i] == j)
{
image(digits[i].digit_image,imgx,imgy);
imgx += digits[0].digit_image.width;
if(imgx>width-digits[0].digit_image.width)
{
imgx = 0;
imgy += digits[0].digit_image.height;
}
}
}
imgx = 0;
imgy += digits[0].digit_image.height*1.25;
stroke(0,255,0);
line(0,imgy,width,imgy);
imgy += digits[0].digit_image.height/4;
}
}
FilenameFilter filter = new FilenameFilter() {
public boolean accept(File dir, String name) {
if (name.toLowerCase().endsWith(“.png”) || name.toLowerCase().endsWith(“.jpg”) || name.toLowerCase().endsWith(“.gif”)) return true;
return false;
}
};

import wekaizing.*;

import java.io.File;

import java.lang.Integer;

class digitImage {

int number;

PImage digit_image;

int[] pixeldata;

public digitImage(int image_size) {

pixeldata = new int[image_size*image_size];}

}

WekaData digits_data;

WekaClusterer clusterer;

digitImage[] digits;

int NUM_DIGITS = 100;

int TRAIN_IMAGE_SIZE = 20;

int NUM_CLUSTERS = 10;

int[] clusters;

PFont courier_font;

void setup() {

background(0);

size(1800,1200);

courier_font = loadFont(“CourierNew-12.vlw”);

textFont(courier_font, 15);

digits_data = new WekaData();

for (int i = 0; i < TRAIN_IMAGE_SIZE*TRAIN_IMAGE_SIZE; i++) {

digits_data.AddAttribute(Integer.toString(i));

}

loadDigits(“digits”);

clusterer = new WekaClusterer(WekaClusterer.EM);

clusters = clusterer.clusterData(digits_data,NUM_CLUSTERS);

print(“Training done”);

drawResults();

}

void loadDigits(String digitfolder) {

File digitfiles = new File(sketchPath, “data/” + digitfolder);

String[] files = digitfiles.list(filter);

if(files.length < NUM_DIGITS)

NUM_DIGITS = files.length;

digits = new digitImage[NUM_DIGITS];

String numbers[] = loadStrings(digitfolder + “/digits.txt”);

for (int i = 0; i<NUM_DIGITS ; i++) {

println(“Loading image ” + files[i]);

digits[i] = new digitImage(TRAIN_IMAGE_SIZE);

digits[i].digit_image = loadImage(“data/” + digitfolder + “/” + files[i]);

digits[i].number = Integer.valueOf(numbers[i]);

PImage resizedImg = loadImage(“data/” + digitfolder + “/” + files[i]);

resizedImg.resize(TRAIN_IMAGE_SIZE,TRAIN_IMAGE_SIZE);

resizedImg.loadPixels();

for (int j = 0; j < TRAIN_IMAGE_SIZE*TRAIN_IMAGE_SIZE; j++) {

digits[i].pixeldata[j] = resizedImg.pixels[j];

}

digits_data.InsertData(digits[i].pixeldata);

}

}

void drawResults() {

int imgx=0, imgy=0;

for (int j=0;j<NUM_CLUSTERS;j++)

{

for (int i = 0; i < digits.length; i++) {

if(clusters[i] == j)

{

image(digits[i].digit_image,imgx,imgy);

imgx += digits[0].digit_image.width;

if(imgx>width-digits[0].digit_image.width)

{

imgx = 0;

imgy += digits[0].digit_image.height;

}

}

}

imgx = 0;

imgy += digits[0].digit_image.height*1.25;

stroke(0,255,0);

line(0,imgy,width,imgy);

imgy += digits[0].digit_image.height/4;

}

}

FilenameFilter filter = new FilenameFilter() {

public boolean accept(File dir, String name) {

if (name.toLowerCase().endsWith(“.png”) || name.toLowerCase().endsWith(“.jpg”) || name.toLowerCase().endsWith(“.gif”)) return true;

return false;

}

};

In this exercise, I used a clustering machine to categorize pictures that contain faces of women in different emotional states as described by Ekman (anger, disgust, fear, joy, sadness, surprise, and contempt). My idea is to see if a machine can actually come across the difference between these emotions as human can do. Apparently, the clustering that came out show more the grouping by the persons instead of the expression, meaning that it didn’t work that well. An idea to improve this could be by subtracting each picture of a person by the mean of her picture.

François

Code

facialexpression

http://paulshen.name/sketches/7

movie_genre

This program clusters movies and genres together, based on some “seed” genres and movies that the user provides: the user can just pick one genre, or one movie, or a mix of genres and movies as seeds.

The user can find a movie or genre by using the prefix search tool (gray box at top left).

To pick an item, just drag it into a colored box (e.g., the yellow one at the bottom left).

Then, the clustering engine, based on the belief propagation, propagates the seeds’ relevance to its neighbors, and then the neighbors’ neighbors, and so on. The seed’s effect on other items diminishes as their distances from the seed increase.

We show the top 5 genres and top 30 movies that are most relevant to the seed items, using spring layout, which shows how the movies and genres are connected.

The visualization can be improved. For example, genres can be layout in a more meaningful way, using variations in colors, orientations, and compositions that reflect the theme formed by the genres.

I’m sorry I can’t post the code, because many packages are used and many files are written. Some of them are “research-ware” that cannot be released yet.

Here I’ve clustered 35 currencies, based on their change of exchange rate with respect to the Euro in the past 2 years.  Each cluster is represented as a gear, and the gears spin together, symbolizing kind of how the world economy spin together…. yeah… Visually there’s much more to be done. In particular, I’d like to give it a more dreary and factory-like look with “dirtier” grimier colors that are associated with both money and gears, grease/oil, both for the text and the background. It’s really way too happy right now given the current economic situation. The gears might also start rattling, seeming to fall apart, to reflect such sentiments. Also, I thought about using actually currency bills as opposed to the text I’m using now, though most people wouldn’t be able to tell which bill corresponds to which country. As we discussed in class, conceptually more exploration of how to represent and discover how the currencies affect each other might be interesting, though I think of currency exchange as a symptom of something with little causality between them. However there probably is a structure where the change in one currency’s value influence another currency’s… etc.

gears

The code can be found here.

  • Create an “Art that Learns” using clustering
  • You can build on the applets we provide, or do your own classifier
  • The notion of classification could invoke many social, political  or ethical issues.  You may want to explore such, or other, connotations, going beyond the ludic qualities of the Childrens Museum
  • Due Date: Thursday, April 2nd in class