Nie taki Linux straszny, jak go malują

posted on Wrzesień 6th, 2009 ·

Moi znajomi znali mnie dotychczas z tego, że lubiłem system Windows do tego stopnia, że nigdy nie przesiadłbym się dobrowolnie na Linuksa do codziennej pracy. Cóż mogę mieć na Linuksie, jeśli tylko kłopoty z niedziałającymi urządzeniami oraz konfigurowaniem wszystkiego w plikach konfiguracyjnych o zakręconej składni. (więcej…)

→ 3 CommentsTags: Systemy operacyjne

Prawa właściciela domeny – transfer i wydanie kodu authinfo

posted on Sierpień 27th, 2009 ·

Niewiele osób wie, jakie są ich prawa jako właścicieli domeny. Znajomość tych praw przydaje się w krytycznym momencie – gdy zbliża się koniec ważności domeny, a koszt przedłużenia u innego rejestratora jest znacznie niższy. (więcej…)

→ 14 CommentsTags: Internet

Maven – podmiana ciągu znaków przed kompilacją

posted on Lipiec 21st, 2009 ·

Dzisiaj w trakcie pracy nad [Scrumowym pluginem][scrumprint] dla Atlassian JIRA odczułem głęboką potrzebę skonfigurowania Mavenowego skryptu budowania w taki sposób, aby wszystkie wystąpienia tokena ${plugin.version} zostały zamieniane na pewien ciąg znaków jeszcze przed kompilacją. (więcej…)

→ No CommentsTags: Java · Programowanie

JIRA Plugin Development w praktyce – potyczki z Mavenem i Atlassianem

posted on Lipiec 10th, 2009 ·

Ostatnio w pracy miałem się zająć rozwinięciem pluginu do Atlassian JIRA, który ma wspomagać pracę zespołu deweloperów w metodologii Scrum (agile). Zadanie – od strony technicznej – było bardzo ciekawe, ponieważ dowiedziałem się, w jaki sposób robi się pluginy do JIRY oraz przy okazji mogłem poznać wycinek architektury dużego systemu, jakim jest JIRA. Miałem również możliwość poznania Mockito, ponieważ nie dało się napisać testów jednostkowych JUnit operujących bezpośrednio na całej Jirze. Nie miało to nawet sensu.

(więcej…)

→ 5 CommentsTags: Java · Programowanie

Z pamiętnika polskiego kierowcy – słupki na drodze

posted on Lipiec 8th, 2009 ·

Prawie dwa tygodnie temu postanowiłem odwiedzić [mojego kolegę i wspólnika][kolo], który mieszka w Warszawie. Jako, że miałem do załatwienia coś po drodze w Tczewie, postanowiłem pojechać nową autostradą do końca, dalej drogą krajową numer 1 do Łysomic przed Toruniem, by tam odbić w stronę Warszawy. (więcej…)

→ 23 CommentsTags: Ogólne

Bitwa programistów, czyli TDD Randori Session

posted on Czerwiec 29th, 2009 ·

Czy widzieliście walczących programistów? Jeśli nie, to wybierzcie się kiedyś na sesję randori. Na czym to polega? Otóż, dwóch programistów siedzi przed jednym komputerem. Jeden z nich pisze kod, drugi zaś go kontroluje i ewentualnie podpowiada. Zasada jest taka, że jeśli jeden pisze test jednostkowy, to drugi pisze implementację. W myśl TDD (test driven development) test jednostkowy pisany jest jako pierwszy. Potem drugi programista pisze tylko tyle implementacji, by zapalił się zielony kolor – czyli przejść nowy test jednostkowy oraz wszystkie poprzednie. Gdy test zakończy się sukcesem, pierwszy programista refaktoryzuje kod kolegi – obserwator widzi zawsze trochę więcej, niż robotnik. ;-) (więcej…)

→ 1 CommentTags: Programowanie · Ynne

COOLuary v.2 i Open Space Technology (Unconference)

posted on Czerwiec 27th, 2009 ·

Dzisiaj uczestniczyłem w pierwszej części konferencji [COOLuary v.2][cool]. Nim jednak podzielę się wrażeniami, opiszę samą ideę konferencji tego typu. (więcej…)

→ 1 CommentTags: Programowanie

Sztuczne sieci neuronowe w Matlabie – zrozum net.IW, LW i b

posted on Maj 26th, 2009 ·

W ramach projektu ze Sztucznej Inteligencji mieliśmy stworzyć sieć neuronową, która będzie odpowiadała, czy punkt S = [x, y] należy do kwadratu spełniającego układ nierówności:

  • x > 2
  • x < 6
  • y > 3
  • y < 7

Sieć neuronowa powinna być utworzona na dwa sposoby.

  1. Poprzez nauczenie sieci neuronowej przykładowymi danymi.
  2. Poprzez ręczne ustawienie wag oraz współczynników poszczególnym neuronom.

Wykonanie punktu pierwszego nie jest zbyt trudne, ponieważ w sieci dostępnych jest bardzo dużo przykładów. Kłopoty rozpoczynają się przy drugim zadaniu. Dokumentacja Neural Toolbox w Matlabie co prawda jest bardzo dobra, ale akurat kwestię ręcznego przypisywania wag opisuje słabo. Stąd też tylko metodą prób i błędów można próbować zrozumieć sposób tworzenia sztucznych sieci neuronowych w Matlabie. Dwa dni prób mam za sobą i teraz mogę się podzielić swoją wiedzą.

Najpierw należy rozpocząć od analizy problemu. Mamy zwrócić wartość 1 dla punktów, które spełniają pewien układ nierówności. Każdy jeden neuron w sieci neuronowej potrafi zrealizować jedną prostą oddzielającą klasy. W związku z tym w warstwie ukrytej sieci neuronowej potrzebujemy czterech neuronów. Wejścia są dwa – x oraz y, a wyjście jest jedno i zwraca wartość 0 lub 1. Szkic pożądanej sieci neuronowej przedstawia się następująco:

Sztuczna sieć neuronowa - klasyfikacja

Sztuczna sieć neuronowa - klasyfikacja

net = newff([-10 10; -10 10], [4 1], {'hardlim', 'hardlim'});
% pierwszy parametr - zakresy kolejnych wejść
% drugi parametr - ilość neuronów w każdej kolejnej warstwie
% trzeci parametr - funkcje przynależności, np. hardlim, tansig, logsig, purelin, satlin

% Obejrzyj na wykresie, jak się zachowują poszczególne funkcje przynależności:
% plot(-10: 0.1 : 10, tansig(-10: 0.1 : 10))

Jak widać, każdy neuron realizuje pewną funkcję. Żeby jednak pierwsze dwa neurony działały poprawnie, należy na ich wejście doprowadzić tylko wartość x. W tym celu ustawiamy wagę wejścia y na 0 dla tych neuronów. Analogicznie czynimy dla neuronów trzeciego i czwartego, ustawiając wagi dla wejść x na 0. Takim zabiegiem sieć neuronowa działa, jak gdyby nie było połączeń pomiędzy wejściem x i dolnymi neuronami oraz wejściem y i górnymi neuronami.

% Tak mniej więcej powinny wyglądać wagi.
% Jedynki mogą się zmienić później, jednak zera zostaną.

% Waga X dla kolejnych neuronów
net.IW{1}(:,1) = [1; 1; 0; 0];
% Waga Y dla kolejnych neuronów
net.IW{2}(:,2) = [0; 0; 1; 1];

Teraz przyjrzymy się pierwszemu neuronowi, mającemu realizować zadanie x > 2. Każdy neuron realizuje pewną matematyczną funkcję. W tym przykładzie funkcję hardlim. Wartość na wyjściu neurona liczona jest wg wzoru: a = hardlim(w * x + b). Zatem, aby funkcja zwracała wartość 1 dla x > 2, współczynnik wagowy w powinien wynosić 1, zaś b -2.

net.IW{1}(1,1) = 1;
net.b{1}(1) = -2;

% Skorzystaj z polecenia nnd2n1, aby wspomóc sobie dobieranie wag graficznie.

Prostą x < 6 zrealizujemy w podobny sposób. Trzeba tylko zmienić stronę – funkcja hardlim ma zwracać wartość 1 nie na prawo, lecz na lewo od szóstki. W tym celu wagę ustawimy na -1, a współczynnik b na 6. Podobne działania wykonujemy dla neuronów dolnych.

Teraz każdy neuron realizuje swoją pożądaną funkcję. Przejdźmy więc do neurona wyjściowego. Neuron wyjściowy powinien zwracać 1 wtedy i tylko wtedy, gdy każdy z neuronów poprzedzających zwrócił wartość 1. Należy wiedzieć, że jeśli do dowolnego neurona podłączone są dwa wejścia i na jednym wejściu wchodzi wartość 2, a na drugim 3, to neuron otrzymuje sumę tych wartości, czyli 5. Z tego wynika, że neuron końcowy powinien zwracać wartość 1 tylko, jeśli na wejściu otrzymał sumę równą 4. W tym celu wagi wszystkich wejść ustawiamy na 1, a współczynnik b na -4.

% Kompletny kod:

% Utworzenie sieci neuronowej o dwóch wejściach i jednym wyjściu
net = newff([-10 10; -10 10], [4 1], {'hardlim', 'hardlim'});

% Ustalenie współczynników b
net.b{1} = [-2; 6; -3; 7];

% Wejście X - wagi wejściowe dla kolejnych neuronów
net.IW{1}(:,1) = [1; -1; 0; 0];
% Wejście Y - wagi wejściowe dla kolejnych neuronów
net.IW{1}(:,2) = [0; 0; 1; -1];

% Ustawienie wag dla neuronów
net.LW{2,1}(1,:) = [1 1 1 1];
net.b{2} = -4;

Zwracam uwagę na nieszczęsne IW oraz LW. net.IW to wagi wejściowe dla pierwszej warstwy neuronów, zaś net.LW to wagi wyjściowe z pierwszej warstwy neuronów.

Wygenerujmy teraz jakieś losowe punkty i sprawdźmy, czy nasza sieć neuronowa działa.

% Wygenerowanie punktów
x1 = rand(1, 80) * 8;
x2 = rand(1, 80) * 8;
obrazy = [x1; x2];
klasy = (obrazy(1,:) > 2) .* (obrazy(1,:) < 6) .* (obrazy(2,:) > 3) .* (obrazy(2,:) < 7 );
ind1 = find(klasy == 0);
ind2 = find(klasy == 1);

% Utworzenie sieci neuronowej o dwóch wejściach i jednym wyjściu
net = newff([-10 10; -10 10], [4 1], {'hardlim', 'hardlim'});

% Ustalenie współczynników b
net.b{1} = [-2; 6; -3; 7];

% Wejście X - wagi wejściowe dla kolejnych neuronów
net.IW{1}(:,1) = [1; -1; 0; 0];
% Wejście Y - wagi wejściowe dla kolejnych neuronów
net.IW{1}(:,2) = [0; 0; 1; -1];

% Ustawienie wag dla neuronów
net.LW{2,1}(1,:) = [1 1 1 1];
net.b{2} = -4;

% Narysowanie wykresu
[X,Y] = meshgrid(0 : 0.1 : 8);
Z = X;
Z(:) = sim(net, [X(:) Y(:)]');
contour(X,Y,Z,[0.499 0.5 0.501]);
hold on
plot(x1(ind1),x2(ind1),'bo',x1(ind2),x2(ind2),'rs')
hold off

Mam nadzieję, że mój artykuł pomógł zrozumieć, w jaki sposób tworzyć sztuczne sieci neuronowe przy pomocy Matlaba. Kluczowym do zrozumienia zagadnienia jest opanowanie właściwości net.IW, net.LW oraz net.b, które są bardzo nieintuicyjne i słabo udokumentowane.

→ 1 CommentTags: Programowanie

Zagadka w języku Java

posted on Maj 18th, 2009 ·

Dzisiaj na mojej uczelni odbywały się coroczne Trójmiejskie Targi Pracy. Jedna z firm przedstawiających swoje oferty, Sygnity, zorganizowała mały konkurs z nagrodami. Konkurs miał 10 pytań o tematyce programistycznej (Java, JEE, SQL, build-scripts). Z testu uzyskałem wynik 9/10. Potknąłem się na rzeczy, której byłem po prostu pewien – na analizie krótkiego kodu w języku Java.

Należy dodać, że nie był to typowy konkurs, w którym pytają o imię głównego bohatera serialu Świat wg Kiepskich, dając do wyboru Zbigniewa, Ferdynanda i Jerzego. Test zgrabnie stwierdzał, czy jesteś oczytany w tematach związanych z programowaniem. Jeden z wykładowców, pan Kaczmarek, mawiał na wykładach o Linuksach, że wiedza jest banalna, jeśli się pozna pelecenie i niemożliwa do wymyślenia, jeśli tego polecenia na oczy nie widzieliśmy.

Poniżej umieszczam zadanie testowe, które mnie wkopało. Kurczę, podium było tak blisko :>

class A {
    public String a = "3";

    public String getA() {
        return this.a;
    }
}

class B extends A {
    public String a = "5";

    public String getA() {
        return this.a;
    }
}

public class C {
    public static void main(String[] args) {
        A a = new B();
        System.out.println(a.a + ", " + a.getA());
    }
}

Jaki będzie wynik działania tego programu?

  • 3, 3
  • 3, 5
  • 5, 3
  • 5, 5

Proponuję najpierw udzielić odpowiedź, a dopiero potem sprawdzić sobie rezultat na żywo. Ja po prostu nie wiedziałem, że tak to działa. Może dlatego, że zgodnie z zasadą enkapsulacji nie pozostawiałem nigdy żadnych publicznych pól? Ale teraz już wiem :-)

P.S. W losowaniu jedną z nagród zgarnął oczywiście Zal, masowy wygrywacz wszystkich konkursów :D Ale dzięki temu miałem przyjemność poznać go osobiście.

→ 5 CommentsTags: Programowanie

Cała prawda o pseudointeligentnym budynku wydziału PG ETI

posted on Maj 13th, 2009 ·

Dzisiaj przypadkowo trafiłem na stronę, na której wychwalano budynek mojego wydziału. Osoba, która nie studiuje na ETI mogłaby naprawdę uwierzyć, że ten budynek jest wręcz perfekcyjny. Niestety, tak nie jest. Ten wpis będzie stanowił uzupełnienie artykułu na MuratorPlus.pl o negatywne strony budynku nowego ETI.

Zacznijmy od audytoriów. Fajnie by było, gdyby na audytoriach siedziało się wygodnie. Z zewnątrz audytorium wygląda bardzo ładnie, jednak wystarczy posiedzieć 20 minut, by przekonać się, że na tych siedzeniach nie idzie po prostu usiedzieć. Stare, komunistyczne audytorium w gmachu wydziału Oceanotechniki, choć ciasne i obskurne, jest wygodniejsze niż to nowe. Bardzo dużo osób zgadza się ze mną, że na audytoriach nie idzie usiedzieć. W dodatku odległość siedzenia od blatu jest zbyt duża – nie idzie pisać w zeszycie, będąc opartym. Można pisać na kolanie, ale chyba nie o to chodzi.

Warto by też zadbać o mazaki. Mazaki na audytoriach i w salach lekcyjnych są prawie zawsze zużyte i tylko pierwsze rzędy mogą cokolwiek przeczytać. Jednak mazaki to drobnostka w porównaniu z nagłośnieniem. Nagłośnienie audytoriów jest po prostu słabe. Jeden wielki głośnik z przodu nie nagłośni wystarczająco całego audytorium. Cicho mówiących wykładowców praktycznie nie słychać w tylnych częściach audytorium. Porównując nagłośnienie do Uniwersytetu Gdańskiego, gdzie miałem przyjemność pisać egzamin FCE, Politechnika wypada bardzo mizernie. Na Uniwerku głośniki znajdowały się w suficie (mnóstwo ich) i w każdym miejscu audytorium głos był jednakowo słyszalny. Pisanie egzaminu w części Listening było przyjemnością. Na ETI nie byłoby to niczym przyjemnym.

Ostatecznie, gdy rozładują się baterie w mikrofonie, w biurku wykładowcy na audytorium nie znajdują się zapasowe baterie. Wykładowca musi iść na dół na portiernię i poprosić o nowe baterie… oczywiście tego nie zrobi, bo zabierze to 5 cennych minut. Dalsza część wykładu odbywa się więc bez mikrofonu. A wysztarczyło umieścić w biurku zapasowe baterie.

Nie tylko audytoria są niewygodne. Krzesła w salach lekcyjnych są również niewygodne – mają tak małe oparcia, że tylko dzieci przedszkolne siedziałyby na nich wygodnie. W dodatku większe osoby nie mieszczą się w ławkach – krzesła są zbyt wysokie, a ławki mają zbyt nisko blat. Efektem jest zgnieciona górna część nóg. I znowu stare, 20-letnie krzesła i ławki okazują się wygodniejsze, niż te nowe.

W budynku działa sieć bezprzewodowa WETI_PG. Szkoda tylko, że moc sygnału jest tak słaba, że korzystanie z Internetu w audytoriach jest utrudnione, a czasem niemożliwe. W tak nowoczesnym budynku zapomniano też o tym, by laptopy wykładowców miały dostęp do Internetu (te laptopy, które stoją na stałe w audytoriach). W bibliotece znajduje się ok. 30 stanowisk komputerowych. Dobrze by było, ażeby był na niej dostęp do Internetu. W ostatnim tygodniu na moje trzy wizyty, dwa razy sieć nie działała.

Gdyby budynek nosił miano inteligentnego, musi w nim panować normalna temperatura. W laboratoriach komputerowych często jest albo zbyt gorąco albo zbyt zimno. Sporadycznie zdarza się wąchać smród z klimatyzacji. Ewenementem jest biblioteka, w której zawsze jest tak gorąco, że chciałoby się po prostu siedzieć na gołej klacie.

I jeszcze mały szczegół, w sumie mało ważny, ale zawsze – drzwi frontowe, jak i boczne otwierają się bardzo wolno.

Myślę, że projektując ten superinteligentny budynek zapomniano o rzeczach podstawowych – budynek ETI powinien być przede wszystkim wygodny, a dopiero potem funkcjonalny i zbajerowany.

→ 11 CommentsTags: Ogólne