CPSC 420-502 Read-Only Bulletin Board

Last modified:

This page will have all relevant email transactions with the students regarding the AI course, so that everyone has equal information regarding the course material.

Newest transactions will be posted on the top. Regularly view this page to see what's going on between other students and the instructor.

All sensitive material such as your name, email address, etc. will be removed, and also any part of code that is not relevant to the discussion will not be uploaded here.

* You may also take a peek at the Graduate AI board.


****************************************************************************
Sat Dec 14 13:26:16 CST 2002
[Q] For the backprop timing vs. number of epoch experiment, do I repeat 5.1 or
    5.2?

[A] Do it for 5.2, the hidden unit experiments.

****************************************************************************
Sat Dec 14 11:51:15 CST 2002
[Q] I was working on the perceptron part of the project, part 5.1 question
	3(d).  I looked at your table 1 and noticed that you have:

	X Y | !(X /\ Y)
	--------------
	0 0 |   1
	0 1 |   0
	1 0 |   0
	1 1 |   0

	shouldn't this be:

	X Y | !(X /\ Y)
	--------------
	0 0 |   1
	0 1 |   1
	1 0 |   1
	1 1 |   0

	Am I overlooking something or is the table wrong?

[A] You're right. That was another typo. Fix X /\ Y to X \/ Y.

****************************************************************************
Sat Dec 14 09:50:49 CST 2002
----------------------------------------------------------------------------
[Q] I am confused about the final exam material. Are you going to 
    put up a past exam?

[A] No. I will not put up a past exam. The exam style will be similar to 
    the midterm and you can look at the homework for a clue too.

    As for the material, I won't ask you to derive the backprop learning
    rule or anything. Just think about these things:

	1. what is the core idea?
	2. what are the major breakthroughs made by the algorithm? i.e.,
		what kind of unsolvable problem in a previous
		approach was solved in this one?
	3. what are the major advantages?
	4. what are the limitations?

    That was for neural networks stuff.

    As for other topics, think about the core concept. For example,
    what is the single most important concept that allows Bayesian
    updating to be efficient?

    Think and study in that level.

    There will be some problems as in the homework that may require
    some precise application of your knowledge as well, so work on 
    that aspect as well.

----------------------------------------------------------------------------

[Q] What should the range of the weights be initially?

[A] Between 0.0 and 1.0, inclusive.

----------------------------------------------------------------------------

[Q] Right below figure 1., it says "Your program should take 5 inputs"...
    Isn't it three? 

		max epochs
		learning rate 
		function name to learn

[A] Yes, you're right. That was a typo.

----------------------------------------------------------------------------

[Q] I don't understand how to take in the input. Is is supposed to be
    command line arguments? If not what?

[A] Just read a single line from standard input (scanf(...) or cin << ..., etc.)

----------------------------------------------------------------------------

[Q] Can I use GUI?

[A] I recommend that you do not use GUI at all, but if that's all you can
    do (i.e., you cannot possibly do command line), then you may.

----------------------------------------------------------------------------

[Q] Some output can get really long -- for example, the weight dump
    in the perceptron. Do you really want all that?

[A] If it is too long, you can just put the first 10 and last 10 lines
    in the README file.

----------------------------------------------------------------------------

[Q] The sum of square error is the same. It's too long. What do I do?

[A] If you look carefully, the error stays the same for a long stretch
    of time. Just report the epoch when it actually changes.

	epoch error
	100   2
	..
	1000  2
	...
	1989  2	
	1999  1 	<---
	...

----------------------------------------------------------------------------

[Q] For the backprop, how do I plot the error?

[A] First of all, the instruction in the README file is incorrect.

    This will give you the epoch and error:

	./bp conf/xor.conf | grep ERR	

	ERR 1 0.1xxxx
	ERR 2 0.09xxx
	...

    However, there's that string 'ERR' in the front, so you don't
    want that. To get rid of that, use awk:

	./bp conf/xor.conf | grep ERR | awk '{print $2,$3}'

    This will print the 2nd and 3rd ($2 and $3) column:

	1 0.1xxxx
	2 0.09xxx
	...

    Once you have this, you can plot it in any data or graphics
    package. Excel may be useful if you don't know how to plot
    in Matlab.

----------------------------------------------------------------------------
[Q] I cannot save the plot to an image file. What to do?

[A] Print it out and bring it to the final.

----------------------------------------------------------------------------
[Q] I am confused about how to plot the error curve. Do I plot all the 
    plots separately? or all in one? if not, how to group them?
    This is about 5.2, experiment 1, and experiment 2

[A] 

    For experiment 1, each plot should be dedicated to one 
    function (one of AND, OR, or XOR).
    
    1st plot: AND -- for alpha 0.01, 0.001, 0.0001

    2nd plot: OR  -- for alpha 0.01, 0.001, 0.0001

    ..

    For experiment 2, the same goes:

    1st plot: AND -- for 1, 2, 3, and 4 hidden units

    2nd plot: OR  -- for 1, 2, 3, and 4 hidden units

    ..

----------------------------------------------------------------------------

[Q] I am confused about the loop stopping criteria. If I cancluate the
    squared error for each input pattern (for the 4 input patterns),
    it would be different and I can get kicked out of the loop
    as soon as at least one of the inputs give zero error. What do I do?

[A] That's why you want to use the "sum" of squared errors.

	     Sum	( Ti - Oi)^2
	i = Input1 to 4

----------------------------------------------------------------------------

[Q] I am confused about section 5.1, 3(b). I don't know what you want?

[A] Think about the two problems in geometric terms. You may also run
    experiments and find the average number of epochs to get an 
    empirical answer, from which you can think about the reason why.

----------------------------------------------------------------------------

[Q] In section 5.1, 3(c), ohw many times is "many"? 

[A] Try 5 times each for the 4 inputs, and see if you get any meaningful
    result. If not, try 10 times each, etc.

----------------------------------------------------------------------------

[Q] This is odd. When I run backprop with 1 hidden unit and bias turned
    on, the output dump suggests that there are 2, not 1, hidden units.

[A] That is normal, because a bias unit is added at each input and hidden
    layers, and is counted as an extra hidden unit by the program. 

    Don't be concerned about it and just set 1, 2, 3, and 4 for 
    the hidden unit size to do your experiment 5.2.

----------------------------------------------------------------------------

[Q] I programmed in JAVA, and it doesn't produce any executable. What
    do I submit?

[A] Just submit the class file along with the other stuff.

----------------------------------------------------------------------------

[Q] Wait! Some answeres you gave above conflict with the answer you
    gave me earlier!

[A] In that case, clearly mark that fact on your submission, and
    you do not have to follow the guideline written above.


****************************************************************************
Wed Nov 13 11:40:15 CST 2002

[Q] I have a lot of questions about the written homework. Is there any
    tip?

[A] See the graduate student board.

****************************************************************************
Thu Oct 17 12:06:11 CDT 2002

[Q] I can't figure out what that (funcall ...) in the (expand ...) function
    in the skeleton code eight-util.lsp does!?

[A] You can safely ignore that function and write (expand ...) on your
    own.

    Here's how I was using it, but you don't have to do it this way at 
    all.

    (defun dfs ...

	...
	(setq *expand-func* 'expand-uninformed)
	...
    )


    (defun heuristic ...
	
	...
	(setq *expand-func* 'expand-informed)
	...
    )

    (defun expand-uninformed (node)
	...
	; update depth d
	...
    )

    (defun expand-informed (node)
	...
	; update depth d
	; update heuristic h
	...
    )

    So, the core routine did not have to worry about calling expand-uninformed
    or expand-informed depending on the need. 


****************************************************************************
Thu Oct 17 11:57:14 CDT 2002

[Q] My (append ....) does not seem to work in my (expand ...)!

[A] (append list-a list-b) RETURNS the appended list (list-a list-b).
    It does NOT append list-b to list-a and update list-a.
    So, to achieve that, you have to do

	(setq list-a (append list-a list-b))

	cf.  list_a = append(list_a,list_b); /* in C/JAVA ..*/

    For example, suppose you have a local variable that holds the
    current list of nodes expanded from a certain node:

	(setq tmp-expanded-node (cons (apply-op ...) tmp-expanded-node)

    Note that here I used cons instead of append, because (apply-op ..)
    returns a node, not a node list. 

    Here's an example:

>(setq x '(1 2))
(1 2)

>(setq x (cons 3 '(1 2)))	; notice that cons was used
(3 1 2)

>(setq x '(1 2))		 
(1 2)

>(setq x (append '(3) '(1 2)))  ; here to use append, 3 had to be a list.
(3 1 2)

****************************************************************************
Thu Oct 17 11:54:46 CDT 2002

[Q] How do I make a state into a node? I have no idea.

[A] Node is a list of 4 items: state, heuristic value, depth value, and
    a list of operators, which is the path.

    In Lisp you use (list ...) to generate a list of objects:

    (defun dfs (state)

	...

	(setq node (list state 0 0 NIL))

	...
    )

    Basically, you make an initial node by making a list of the 
    provided state, heuristics 0, depth 0, and an empty list of operators
    as the current path.

****************************************************************************
Thu Oct 17 11:51:58 CDT 2002

[Q] It is really hard to debug my code in Lisp. How do I get about locating
    the exact cause of the error?

[A] Use the (trace ...) command to turn on the trace for the important 
    functions:

	(trace dfs)
	(trace dfs-core)
	(trace expand)
	(trace applicable)
	(trace apply-op)

    and then run your dfs

	(dfs '(1 2 3 4 5 6 7 8 0))

    The benefit of this is that it shows you what are the arguments
    passed on to the functions and also what is returned. 
    You can then determine what was the flaw in your calling routine.

> (trace bfs)
(BFS)

> (trace bfs-core)
(BFS-CORE)

> (trace expand)
(EXPAND)

> (bfs '(1 2 3 4 7 5 6 0 8))
  1> (BFS (1 2 3 4 7 5 6 0 8))
    2> (BFS-CORE (((1 2 3 4 7 5 6 0 8) 0 0 NIL)))
      3> (EXPAND ((1 2 3 4 7 5 6 0 8) 0 0 NIL))		; expand is called
      <3 (EXPAND (((1 2 3 4 7 5 6 8 0) 10000 1 (RIGHT)) ; expand returns this 
                  ((1 2 3 4 7 5 0 6 8) 10000 1 (LEFT))		list
                  ((1 2 3 4 0 5 6 7 8) 10000 1 (UP))))
      3> (BFS-CORE
             (((1 2 3 4 7 5 6 8 0) 10000 1 (RIGHT))
              ((1 2 3 4 7 5 0 6 8) 10000 1 (LEFT))
              ((1 2 3 4 0 5 6 7 8) 10000 1 (UP))))
        4> (EXPAND ((1 2 3 4 7 5 6 8 0) 10000 1 (RIGHT)))
        <4 (EXPAND (((1 2 3 4 7 5 6 0 8) 10001 2 (LEFT RIGHT))
                    ((1 2 3 4 7 0 6 8 5) 10001 2 (UP RIGHT))))
        4> (BFS-CORE
               (((1 2 3 4 7 5 0 6 8) 10000 1 (LEFT))
                ((1 2 3 4 0 5 6 7 8) 10000 1 (UP))
                ((1 2 3 4 7 5 6 0 8) 10001 2 (LEFT RIGHT))
                ((1 2 3 4 7 0 6 8 5) 10001 2 (UP RIGHT))))
          5> (EXPAND ((1 2 3 4 7 5 0 6 8) 10000 1 (LEFT)))
          <5 (EXPAND (((1 2 3 0 7 5 4 6 8) 10001 2 (UP LEFT))))
          5> (BFS-CORE
                 (((1 2 3 4 0 5 6 7 8) 10000 1 (UP))
                  ((1 2 3 4 7 5 6 0 8) 10001 2 (LEFT RIGHT))
                  ((1 2 3 4 7 0 6 8 5) 10001 2 (UP RIGHT))
                  ((1 2 3 0 7 5 4 6 8) 10001 2 (UP LEFT))))

	If anything goes wrong in EXPAND, you'll notice it.


****************************************************************************
Wed Oct 16 17:05:36 CDT 2002

[Q] Why do I need to use (let ...) at all?

[A] Because if you have same variable names in two different 
    functions, they will interfere. Look at this example:

>(defun xx ()     		; define function xx
        (setq x 10))		; set variable x to 10
XX

>(defun yy ()			; define function yy
        x)			; return variable x
YY

>(xx)				; running xx will set x to 10
10

>(yy)				; even though x is inside yy, it will
10				; be affected by the previous (xx) call.

****************************************************************************
Mon Oct 14 16:02:13 CDT 2002

[Q] Why doesn't my (let ...) statement work?

	(let (current-node (car node-list)))
	...
	(setq node-list (append (expand current-node) (cdr node-list)))
	...

[A] The (let ...) form is effective only within its parentheses. So, the
    above example would be interpreted as the following, say in psudo-C:

		{
			TYPE	current_node;
		}
		...
		node_list = append(expand(current_node), cdr(node_list));

    So, the assignment will fail.

    The above should be changed to

	(let (   (current-node (car node-list))   )
	    ...
	    (setq node-list (append (expand current-node) (cdr node-list)))
	    ...
	)

    Also note that the syntax for (let ...) is:

		(let (var1 var2 var3 ...)

			BODY

		)

   or, if you want to initialize (some of) the variables,

		(let (var1 (var2 10) (var3 20) var4 ...)

			BODY

		)

   Note that var1 and var4 are uninitialized, while var2 and var3 are
   initialized to 10 and 20, respectively.

   The best strategy is to have (let ...) to be the outer-most 
   expression in a function:


	(defun fun-name (arg1 arg2 ...)
		(let (var1 (var2 5) var3 ...)

			BODY

		)
 	)

****************************************************************************
Sun Oct 13 22:08:35 CDT 2002

[Q] My dupe check fails the second time I run any search function. 
    My explored node global variable is not empty when I start the 
    second call.

[A] You have to reset your explored node list before starting a new
    search. Suppose *explored* was your list:

	(defvar *explored* nil) 

    then within each search function, run

		(setq *explored* nil)

****************************************************************************
Sun Oct 13 22:06:57 CDT 2002

[Q] Do I need to come up with a heuristic?

[A] No, just implement h1 (tiles out-of-place) and h2 (total manhattan 
    distance). If you want to try new ones, that's fine, but make sure
    you do h1 and h2.

****************************************************************************
Sun Oct 13 22:05:55 CDT 2002

[Q] My dupe check fails! -- see below.

>  (dupe '(1 2 3 8 4 0 7 6 5)
>   '((1 2 3 8 4 0 7 6 5) (1 2 3 8 4 5 7 0 6) (1 2 0 8 4 3 7 6 5)
>     (1 2 3 8 0 4 7 6 5) (1 2 3 8 4 5 7 6 0) (1 2 3 8 0 5 7 4 6)
>     (1 2 3 8 4 5 0 7 6) (1 2 3 8 4 5 7 6 0) (1 0 2 8 4 3 7 6 5)
>     (1 2 3 8 4 0 7 6 5) (1 2 3 8 4 0 7 6 5) (1 2 3 8 4 5 7 0 6)
>     (1 2 0 8 4 3 7 6 5) (1 2 3 8 0 4 7 6 5) (1 2 3 8 4 5 7 6 0)
>     (1 2 3 8 0 5 7 4 6) (1 2 3 8 4 5 0 7 6) (1 2 3 8 4 5 7 6 0)
>     (1 0 2 8 4 3 7 6 5) (1 2 3 8 4 0 7 6 5) (1 2 3 8 4 0 7 6 5)
>     (1 2 3 8 4 5 7 0 6) (1 2 0 8 4 3 7 6 5) (1 2 3 8 0 4 7 6 5)
>     (1 2 3 8 4 5 7 6 0) (1 2 3 8 0 5 7 4 6) (1 2 3 8 4 5 0 7 6)
>     (1 2 3 8 4 5 7 6 0) (1 0 2 8 4 3 7 6 5) (1 2 3 8 4 0 7 6 5)))

[A] Notice that dupe checks a "state" agains a "explored-node-list".
    Note that this "explored-node-list" is different from the 
    node-list you have in the search function!

	(dupe '(1 2 3 8 4 0 7 6 5)
		(
			((1 2 3 ..) 0 1 (UP))                   ; node 1
			((1 2 3 8 ..) 2 2 (DOWN LEFT))          ; node 2
			...
		)
	)

****************************************************************************
Fri Oct 11 19:42:58 CDT 2002

[Q] I am not clear about how to check for duplicate states. Do I check
    for duplicate against the node-list?

[A] No. The node-list only contains unexplored nodes that have been
    expanded from other (already checked) nodes so far. 
    You may have to keep a global variable, say

	(defvar *explored* NIL)

    and whenever you pop one node to check for goal and expand, push
    that node in the *explored* list. Keep updating this list whenever
    you take a node out of the node-list, and when you generate new
    nodes, simply run dupe to check if it occured in *explored*.

    Updating and check for the *explored* list should be done 
    in (expand ...).

****************************************************************************
Fri Oct 11 19:41:08 CDT 2002

[Q] How do I write a loop in Lisp?

[A] In case you really want to write a loop, here's a simple example:

	>(setq x 1)
	1

	>(loop    
		(setq x (+ x 1))
		(if (> x 20) (return x))
	 )
	21

    In the "loop" function, when it encounters "return" it exits the
    loop and returns the value specifiec by "return" as the value of the
    whole (loop ... ) expression.

****************************************************************************
Thu Sep 19 13:52:20 CDT 2002

[Q]
> In the function deriv, how should we go about unary minus, since its symbol
> is exactly the same as the subtraction symbol. I understand how to struction
> the function derivminus, but am confused how to add its function call to
> deriv.

[A]

I discussed this in the class.

Basically, instead of checking if

        (equal (first expr) '-)

add an additional condition

        (and (equal (first expr) '-)
             (equal (length expr) 3))

for binary, and check for length 2 for unary.



****************************************************************************
Thu Sep 19 12:34:35 CDT 2002

[Q] 
> I noticed on the Novak code posted that the multiplication function doesn't
> simplify very much. For example, when I run (derivtimes '(* x x) 'x) it gives
> me (+ x x) as the answer (2x). In our code are we then supposed to call splus
> so that the answer simplifies down to 2x?
> 
> I guess the basic nature of my question is this: is the Novak code including
> the multiplication as is and ready to go, or do we need to modify it further.
  
[A]
        If your derivXXXX uses the simplification functions splus, smult,    
        etc. in place of (list '+ ...), (list '* ....) etc., then that's
        fine and no further simplification is necessary beyond that.


****************************************************************************
Thu Sep 19 12:17:52 CDT 2002

[Q] My program returns an answer that is mathematically correct but it
    is different from the test output you provided in the lecture slide.
    Is this okay?

[A] Of course! As long as your result is mathematically correct, you're fine.

****************************************************************************
Thu Sep 19 09:59:18 CDT 2002

[Q] Do I need to use "tar" to create a single file when submitting?

[A] Well, if you find it difficult, you may just submit individual files:

	turnin 420-502 deriv.lsp README another-files yet-another-file 

    After that, to check if everything was submitted correctly, do

	turnin -c 420-502

****************************************************************************
Wed Sep 18 14:34:21 CDT 2002

[Q] How do I deal with unary minus?

[A] First, the derivation rule is:

	d(-f)	   d(f)
	-----  = - ----
	 dx	    dx

    Next, the problem is how to simplify it. When given

	(- expr)

    the simplest one is:

	if (expr == 0), return 0.

    If you want to go a bit further, you can reduce
	
	(- 12)

    to just

	-12

    So, basically generate a negative number.

    You can do this by first checking if expr is a number, and returning

	(* -1 expr)

****************************************************************************
Wed Sep 18 12:11:31 CDT 2002

[Q] What do I do if the denominator is zero in case of division?

[A] Just check for that condition and generate an error message and
    terminate the program.

****************************************************************************
Wed Sep 18 11:59:51 CDT 2002

[Q] How do I save the output from the GCL runs?

[A] Use the unix command "script" to save your entire session to a text file.
    Bold text is what I entered. Italisized text is the
    command prompts. The "script" command allows you to save whatever
    appears on the screen in to a file you designate (below, it is 
    outputfile). Beware!: script overwrites the file,
    so be very careful when running the script command. If you did
    script deriv.lsp, that would be a disaster!!.

unix:~/> script outputfile
Script started, file is outputfile
%gcl
GCL (GNU Common Lisp)  Version(2.3) Wed Feb 14 16:09:29 CST 2001
Licensed under GNU Library General Public License
Contains Enhancements by W. Schelter

>(load "deriv.lsp")

Loading deriv.lsp
Finished loading deriv.lsp
T

>(deriv '(* x x) 'x)

Error: The function DERIVMULT is undefined.
Fast links are on: do (si::use-fast-links nil) for debugging
Error signalled by COND.
Broken at COND.  Type :H for Help.
>>:q

Top level.
%exit
exit
Script done, file is outputfile


****************************************************************************
Wed Sep 18 11:52:04 CDT 2002

[Q] How do I save the programs I typed in inside a GCL shell?

[A] There's no way of saving your work typed in inside of GCL. 
    You should write a separate program file on the disk and run 

		(load "deriv.lsp") 

    inside GCL to test the code.



	1. edit your program in deriv.lsp, for exmaple with pico.
	2. start gcl
	3. inside gcl, run
		
		(load "deriv.lsp")

	4. still inside gcl, run 

		(deriv '(* x x)' x)

	   and etc.

	5. If there is an error, type

		:q

	   and edit your file deriv.lsp. Reload deriv.lsp in gcl

		(load "deriv.lsp")

	   and test it again.

		(deriv '(* x x)' x)

	*. So, basically, you need to have two terminal windows up, one 
	   for editing the code, and one for testing the code (in gcl).

****************************************************************************
Wed Sep 18 11:50:08 CDT 2002

[Q] What do I need to put in the README file?

[A] Briefly describe how your program works, and show example runs.
    Discuss what you think about the program: is it intelligent? Why so or
    why not?

****************************************************************************
Wed Sep 18 11:50:01 CDT 2002

[Q] Can I use the deriv.lsp on Gordon Novak's ftp site?

[A] Yes, you may. I made a link to that code in the news box. It includes
    a simple implementation of multiplication as well as the addition
    routine.